<!DOCTYPE html>
<html>

<head>
  <title>readme</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css">









  <style>
    /**
 * prism.js Github theme based on GitHub's theme.
 * @author Sam Clarke
 */
    code[class*="language-"],
    pre[class*="language-"] {
      color: #333;
      background: none;
      font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
      text-align: left;
      white-space: pre;
      word-spacing: normal;
      word-break: normal;
      word-wrap: normal;
      line-height: 1.4;

      -moz-tab-size: 8;
      -o-tab-size: 8;
      tab-size: 8;

      -webkit-hyphens: none;
      -moz-hyphens: none;
      -ms-hyphens: none;
      hyphens: none;
    }

    /* Code blocks */
    pre[class*="language-"] {
      padding: .8em;
      overflow: auto;
      /* border: 1px solid #ddd; */
      border-radius: 3px;
      /* background: #fff; */
      background: #f5f5f5;
    }

    /* Inline code */
    :not(pre)>code[class*="language-"] {
      padding: .1em;
      border-radius: .3em;
      white-space: normal;
      background: #f5f5f5;
    }

    .token.comment,
    .token.blockquote {
      color: #969896;
    }

    .token.cdata {
      color: #183691;
    }

    .token.doctype,
    .token.punctuation,
    .token.variable,
    .token.macro.property {
      color: #333;
    }

    .token.operator,
    .token.important,
    .token.keyword,
    .token.rule,
    .token.builtin {
      color: #a71d5d;
    }

    .token.string,
    .token.url,
    .token.regex,
    .token.attr-value {
      color: #183691;
    }

    .token.property,
    .token.number,
    .token.boolean,
    .token.entity,
    .token.atrule,
    .token.constant,
    .token.symbol,
    .token.command,
    .token.code {
      color: #0086b3;
    }

    .token.tag,
    .token.selector,
    .token.prolog {
      color: #63a35c;
    }

    .token.function,
    .token.namespace,
    .token.pseudo-element,
    .token.class,
    .token.class-name,
    .token.pseudo-class,
    .token.id,
    .token.url-reference .token.variable,
    .token.attr-name {
      color: #795da3;
    }

    .token.entity {
      cursor: help;
    }

    .token.title,
    .token.title .token.punctuation {
      font-weight: bold;
      color: #1d3e81;
    }

    .token.list {
      color: #ed6a43;
    }

    .token.inserted {
      background-color: #eaffea;
      color: #55a532;
    }

    .token.deleted {
      background-color: #ffecec;
      color: #bd2c00;
    }

    .token.bold {
      font-weight: bold;
    }

    .token.italic {
      font-style: italic;
    }


    /* JSON */
    .language-json .token.property {
      color: #183691;
    }

    .language-markup .token.tag .token.punctuation {
      color: #333;
    }

    /* CSS */
    code.language-css,
    .language-css .token.function {
      color: #0086b3;
    }

    /* YAML */
    .language-yaml .token.atrule {
      color: #63a35c;
    }

    code.language-yaml {
      color: #183691;
    }

    /* Ruby */
    .language-ruby .token.function {
      color: #333;
    }

    /* Markdown */
    .language-markdown .token.url {
      color: #795da3;
    }

    /* Makefile */
    .language-makefile .token.symbol {
      color: #795da3;
    }

    .language-makefile .token.variable {
      color: #183691;
    }

    .language-makefile .token.builtin {
      color: #0086b3;
    }

    /* Bash */
    .language-bash .token.keyword {
      color: #0086b3;
    }

    /* highlight */
    pre[data-line] {
      position: relative;
      padding: 1em 0 1em 3em;
    }

    pre[data-line] .line-highlight-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      background-color: transparent;
      display: block;
      width: 100%;
    }

    pre[data-line] .line-highlight {
      position: absolute;
      left: 0;
      right: 0;
      padding: inherit 0;
      margin-top: 1em;
      background: hsla(24, 20%, 50%, .08);
      background: linear-gradient(to right, hsla(24, 20%, 50%, .1) 70%, hsla(24, 20%, 50%, 0));
      pointer-events: none;
      line-height: inherit;
      white-space: pre;
    }

    pre[data-line] .line-highlight:before,
    pre[data-line] .line-highlight[data-end]:after {
      content: attr(data-start);
      position: absolute;
      top: .4em;
      left: .6em;
      min-width: 1em;
      padding: 0 .5em;
      background-color: hsla(24, 20%, 50%, .4);
      color: hsl(24, 20%, 95%);
      font: bold 65%/1.5 sans-serif;
      text-align: center;
      vertical-align: .3em;
      border-radius: 999px;
      text-shadow: none;
      box-shadow: 0 1px white;
    }

    pre[data-line] .line-highlight[data-end]:after {
      content: attr(data-end);
      top: auto;
      bottom: .4em;
    }

    html body {
      font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
      font-size: 16px;
      line-height: 1.6;
      color: #333;
      background-color: #fff;
      overflow: initial;
      box-sizing: border-box;
      word-wrap: break-word
    }

    html body>:first-child {
      margin-top: 0
    }

    html body h1,
    html body h2,
    html body h3,
    html body h4,
    html body h5,
    html body h6 {
      line-height: 1.2;
      margin-top: 1em;
      margin-bottom: 16px;
      color: #000
    }

    html body h1 {
      font-size: 2.25em;
      font-weight: 300;
      padding-bottom: .3em
    }

    html body h2 {
      font-size: 1.75em;
      font-weight: 400;
      padding-bottom: .3em
    }

    html body h3 {
      font-size: 1.5em;
      font-weight: 500
    }

    html body h4 {
      font-size: 1.25em;
      font-weight: 600
    }

    html body h5 {
      font-size: 1.1em;
      font-weight: 600
    }

    html body h6 {
      font-size: 1em;
      font-weight: 600
    }

    html body h1,
    html body h2,
    html body h3,
    html body h4,
    html body h5 {
      font-weight: 600
    }

    html body h5 {
      font-size: 1em
    }

    html body h6 {
      color: #5c5c5c
    }

    html body strong {
      color: #000
    }

    html body del {
      color: #5c5c5c
    }

    html body a:not([href]) {
      color: inherit;
      text-decoration: none
    }

    html body a {
      color: #08c;
      text-decoration: none
    }

    html body a:hover {
      color: #00a3f5;
      text-decoration: none
    }

    html body img {
      max-width: 100%
    }

    html body>p {
      margin-top: 0;
      margin-bottom: 16px;
      word-wrap: break-word
    }

    html body>ul,
    html body>ol {
      margin-bottom: 16px
    }

    html body ul,
    html body ol {
      padding-left: 2em
    }

    html body ul.no-list,
    html body ol.no-list {
      padding: 0;
      list-style-type: none
    }

    html body ul ul,
    html body ul ol,
    html body ol ol,
    html body ol ul {
      margin-top: 0;
      margin-bottom: 0
    }

    html body li {
      margin-bottom: 0
    }

    html body li.task-list-item {
      list-style: none
    }

    html body li>p {
      margin-top: 0;
      margin-bottom: 0
    }

    html body .task-list-item-checkbox {
      margin: 0 .2em .25em -1.8em;
      vertical-align: middle
    }

    html body .task-list-item-checkbox:hover {
      cursor: pointer
    }

    html body blockquote {
      margin: 16px 0;
      font-size: inherit;
      padding: 0 15px;
      color: #5c5c5c;
      background-color: #f0f0f0;
      border-left: 4px solid #d6d6d6
    }

    html body blockquote>:first-child {
      margin-top: 0
    }

    html body blockquote>:last-child {
      margin-bottom: 0
    }

    html body hr {
      height: 4px;
      margin: 32px 0;
      background-color: #d6d6d6;
      border: 0 none
    }

    html body table {
      margin: 10px 0 15px 0;
      border-collapse: collapse;
      border-spacing: 0;
      display: block;
      width: 100%;
      overflow: auto;
      word-break: normal;
      word-break: keep-all
    }

    html body table th {
      font-weight: bold;
      color: #000
    }

    html body table td,
    html body table th {
      border: 1px solid #d6d6d6;
      padding: 6px 13px
    }

    html body dl {
      padding: 0
    }

    html body dl dt {
      padding: 0;
      margin-top: 16px;
      font-size: 1em;
      font-style: italic;
      font-weight: bold
    }

    html body dl dd {
      padding: 0 16px;
      margin-bottom: 16px
    }

    html body code {
      font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
      font-size: .85em !important;
      color: #000;
      background-color: #f0f0f0;
      border-radius: 3px;
      padding: .2em 0
    }

    html body code::before,
    html body code::after {
      letter-spacing: -0.2em;
      content: "\00a0"
    }

    html body pre>code {
      padding: 0;
      margin: 0;
      font-size: .85em !important;
      word-break: normal;
      white-space: pre;
      background: transparent;
      border: 0
    }

    html body .highlight {
      margin-bottom: 16px
    }

    html body .highlight pre,
    html body pre {
      padding: 1em;
      overflow: auto;
      font-size: .85em !important;
      line-height: 1.45;
      border: #d6d6d6;
      border-radius: 3px
    }

    html body .highlight pre {
      margin-bottom: 0;
      word-break: normal
    }

    html body pre code,
    html body pre tt {
      display: inline;
      max-width: initial;
      padding: 0;
      margin: 0;
      overflow: initial;
      line-height: inherit;
      word-wrap: normal;
      background-color: transparent;
      border: 0
    }

    html body pre code:before,
    html body pre tt:before,
    html body pre code:after,
    html body pre tt:after {
      content: normal
    }

    html body p,
    html body blockquote,
    html body ul,
    html body ol,
    html body dl,
    html body pre {
      margin-top: 0;
      margin-bottom: 16px
    }

    html body kbd {
      color: #000;
      border: 1px solid #d6d6d6;
      border-bottom: 2px solid #c7c7c7;
      padding: 2px 4px;
      background-color: #f0f0f0;
      border-radius: 3px
    }

    @media print {
      html body {
        background-color: #fff
      }

      html body h1,
      html body h2,
      html body h3,
      html body h4,
      html body h5,
      html body h6 {
        color: #000;
        page-break-after: avoid
      }

      html body blockquote {
        color: #5c5c5c
      }

      html body pre {
        page-break-inside: avoid
      }

      html body table {
        display: table
      }

      html body img {
        display: block;
        max-width: 100%;
        max-height: 100%
      }

      html body pre,
      html body code {
        word-wrap: break-word;
        white-space: pre
      }
    }

    .markdown-preview {
      width: 100%;
      height: 100%;
      box-sizing: border-box
    }

    .markdown-preview .pagebreak,
    .markdown-preview .newpage {
      page-break-before: always
    }

    .markdown-preview pre.line-numbers {
      position: relative;
      padding-left: 3.8em;
      counter-reset: linenumber
    }

    .markdown-preview pre.line-numbers>code {
      position: relative
    }

    .markdown-preview pre.line-numbers .line-numbers-rows {
      position: absolute;
      pointer-events: none;
      top: 1em;
      font-size: 100%;
      left: 0;
      width: 3em;
      letter-spacing: -1px;
      border-right: 1px solid #999;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none
    }

    .markdown-preview pre.line-numbers .line-numbers-rows>span {
      pointer-events: none;
      display: block;
      counter-increment: linenumber
    }

    .markdown-preview pre.line-numbers .line-numbers-rows>span:before {
      content: counter(linenumber);
      color: #999;
      display: block;
      padding-right: .8em;
      text-align: right
    }

    .markdown-preview .mathjax-exps .MathJax_Display {
      text-align: center !important
    }

    .markdown-preview:not([for="preview"]) .code-chunk .btn-group {
      display: none
    }

    .markdown-preview:not([for="preview"]) .code-chunk .status {
      display: none
    }

    .markdown-preview:not([for="preview"]) .code-chunk .output-div {
      margin-bottom: 16px
    }

    .scrollbar-style::-webkit-scrollbar {
      width: 8px
    }

    .scrollbar-style::-webkit-scrollbar-track {
      border-radius: 10px;
      background-color: transparent
    }

    .scrollbar-style::-webkit-scrollbar-thumb {
      border-radius: 5px;
      background-color: rgba(150, 150, 150, 0.66);
      border: 4px solid rgba(150, 150, 150, 0.66);
      background-clip: content-box
    }

    html body[for="html-export"]:not([data-presentation-mode]) {
      position: relative;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      margin: 0;
      padding: 0;
      overflow: auto
    }

    html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview {
      position: relative;
      top: 0
    }

    @media screen and (min-width:914px) {
      html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview {
        padding: 2em calc(50% - 457px + 2em)
      }
    }

    @media screen and (max-width:914px) {
      html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview {
        padding: 2em
      }
    }

    @media screen and (max-width:450px) {
      html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview {
        font-size: 14px !important;
        padding: 1em
      }
    }

    @media print {
      html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn {
        display: none
      }
    }

    html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn {
      position: fixed;
      bottom: 8px;
      left: 8px;
      font-size: 28px;
      cursor: pointer;
      color: inherit;
      z-index: 99;
      width: 32px;
      text-align: center;
      opacity: .4
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn {
      opacity: 1
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc {
      position: fixed;
      top: 0;
      left: 0;
      width: 300px;
      height: 100%;
      padding: 32px 0 48px 0;
      font-size: 14px;
      box-shadow: 0 0 4px rgba(150, 150, 150, 0.33);
      box-sizing: border-box;
      overflow: auto;
      background-color: inherit
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar {
      width: 8px
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-track {
      border-radius: 10px;
      background-color: transparent
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-thumb {
      border-radius: 5px;
      background-color: rgba(150, 150, 150, 0.66);
      border: 4px solid rgba(150, 150, 150, 0.66);
      background-clip: content-box
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a {
      text-decoration: none
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul {
      padding: 0 1.6em;
      margin-top: .8em
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc li {
      margin-bottom: .8em
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul {
      list-style-type: none
    }

    html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview {
      left: 300px;
      width: calc(100% - 300px);
      padding: 2em calc(50% - 457px - 150px);
      margin: 0;
      box-sizing: border-box
    }

    @media screen and (max-width:1274px) {
      html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview {
        padding: 2em
      }
    }

    @media screen and (max-width:450px) {
      html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview {
        width: 100%
      }
    }

    html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview {
      left: 50%;
      transform: translateX(-50%)
    }

    html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc {
      display: none
    }

    /* Please visit the URL below for more information: */
    /*   https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */
  </style>
</head>

<body for="html-export">
  <div class="mume markdown-preview  ">
    <h1 class="mume-header" id="sync-sofa-streaming-video-playback-synchronizer-extension">Sync Sofa (streaming video
      playback synchronizer extension)</h1>

    <blockquote>
      <p>This chrome extension allows multi-user sync streaming video in a fast, simple and stable way.</p>
    </blockquote>
    <p><img
        src="https://img.shields.io/github/go-mod/go-version/LouisYLWang/Sync-Sofa?filename=server%2Fgo.mod&amp;style=flat-square"
        alt="GitHub go.mod Go version (subfolder of monorepo)"> <a
        href="https://chrome.google.com/webstore/detail/sync-sofa-beta-online-vid/kgpnhgmpijhpkefpddoehhminpfiddmg"><img
          src="https://img.shields.io/chrome-web-store/users/kgpnhgmpijhpkefpddoehhminpfiddmg?style=flat-square"
          alt="Chrome web store users"></a></p>
    <p>Sync Sofa is a full stack web extension support a easy-to-use and stable way to synchronize streaming playback
      for multiple users. It can improve the experience when users from different locations want to share a video/movie
      remotely. Currently, the feartures include:</p>
    <ul>
      <li>2 party connection: either party can be the host of a sync room and the other can join with connection code.
      </li>
      <li>sync pause/play: each user pause/play the video, the other side will do the same</li>
      <li>sync play process bar control: the playing time change will also affect other side user</li>
      <li>local video sync: provide two ways to sync your playing of local video file</li>
    </ul>
    <h2 class="mume-header" id="current-version">Current version:</h2>

    <p><strong>v1.0.7 - update on 7 July 2020</strong></p>
    <p>&#x26A0;&#x26A0;&#x26A0; Notice, this version is not compatible with any version before 1.0.6 (&lt;= 1.0.5),
      please please please make sure your version is the same as your peer&apos;s version</p>
    <p>Add:<br>
      add version detection (lower version number will be detected from user with higher version number if room was
      established by lower version extension)</p>
    <p>Fix:<br>
      fix support for <a href="https://www.bilibili.com/bangumi/*">https://www.bilibili.com/bangumi/*</a> (bilibili
      movie)<br>
      fix support for Youku &amp; mangoTV</p>
    <hr>
    <div class="code-chunk" data-id="code-chunk-id-0" data-cmd="toc">
      <div class="input-div">
        <div class="btn-group">
          <div class="run-btn btn"><span>&#x25B6;&#xFE0E;</span></div>
          <div class="run-all-btn btn">all</div>
        </div>
        <div class="status">running...</div>
      </div>
      <div class="output-div"></div>
    </div>
    <ul>
      <li><a href="#sync-sofa-streaming-video-playback-synchronizer-extension">Sync Sofa (streaming video playback
          synchronizer extension)</a>
        <ul>
          <li><a href="#current-version">Current version:</a></li>
          <li><a href="#supported-list">Supported list</a></li>
          <li><a href="#setting">Setting</a>
            <ul>
              <li><a href="#server-list">Server list</a></li>
              <li><a href="#options-page">Options page</a></li>
              <li><a href="#refresh-video-page">Refresh video page</a></li>
            </ul>
          </li>
          <li><a href="#usage">Usage</a>
            <ul>
              <li><a href="#notices">Notices</a></li>
              <li><a href="#open-a-video-page">Open a video page</a></li>
              <li><a href="#request-new-code">Request new code</a></li>
              <li><a href="#start-connection">Start connection</a></li>
              <li><a href="#enjoy-yourselves">Enjoy yourselves</a></li>
            </ul>
          </li>
          <li><a href="#vlc-support">VLC support</a>
            <ul>
              <li><a href="#start-vlc-on-the-server-with-the-web-interface">Start VLC on the server with the Web
                  Interface</a></li>
              <li><a href="#request-new-code-1">Request new code</a></li>
              <li><a href="#start-connection-1">Start connection</a></li>
              <li><a href="#enjoy-yourselves-1">Enjoy yourselves</a></li>
              <li><a href="#close-controller-webpage">Close Controller webpage</a></li>
            </ul>
          </li>
          <li><a href="#installation">Installation</a>
            <ul>
              <li><a href="#google-chrome">Google Chrome</a>
                <ul>
                  <li><a href="#install-from-chrome-web-store">Install from Chrome Web Store</a></li>
                  <li><a href="#install-from-local-crx-file">Install from local .crx file</a></li>
                  <li><a href="#install-from-unpackaged-folder">Install from unpackaged folder</a></li>
                </ul>
              </li>
              <li><a href="#microsoft-edge">Microsoft Edge:</a>
                <ul>
                  <li><a href="#install-from-microsoft-edge-addons">Install from Microsoft Edge Addons</a></li>
                </ul>
              </li>
              <li><a href="#firefox-will-be-supported-in-later-version">Firefox (will be supported in later version)</a>
              </li>
            </ul>
          </li>
          <li><a href="#self-hosting-guide">Self-hosting Guide</a>
            <ul>
              <li><a href="#without-docker">Without Docker</a></li>
              <li><a href="#with-docker">With Docker</a></li>
            </ul>
          </li>
          <li><a href="#release-history">Release History</a>
            <ul>
              <li><a href="#v107">v1.0.7</a></li>
              <li><a href="#v106">v1.0.6</a></li>
              <li><a href="#v105">v1.0.5</a></li>
              <li><a href="#v104">v1.0.4</a></li>
              <li><a href="#v103">v1.0.3</a></li>
              <li><a href="#v102">v1.0.2</a></li>
              <li><a href="#v001">v0.0.1</a></li>
            </ul>
          </li>
          <li><a href="#meta">Meta</a></li>
          <li><a href="#contributing">Contributing</a></li>
          <li><a href="#faq">FAQ</a>
            <ul>
              <li><a href="#how-to-get-debug-info">How to get debug info</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a
          href="#sync-sofa-%E5%9C%A8%E7%BA%BF%E8%A7%86%E9%A2%91%E5%90%8C%E6%AD%A5%E6%92%AD%E6%94%BE%E6%8F%92%E4%BB%B6">Sync
          Sofa &#xFF08;&#x5728;&#x7EBF;&#x89C6;&#x9891;&#x540C;&#x6B65;&#x64AD;&#x653E;&#x63D2;&#x4EF6;&#xFF09;</a>
        <ul>
          <li><a
              href="#%E5%BD%93%E5%89%8D%E7%89%88%E6%9C%AC%E7%89%B9%E6%80%A7">&#x5F53;&#x524D;&#x7248;&#x672C;&#x7279;&#x6027;:</a>
          </li>
          <li><a
              href="#%E6%94%AF%E6%8C%81%E7%BD%91%E7%AB%99%E5%88%97%E8%A1%A8">&#x652F;&#x6301;&#x7F51;&#x7AD9;&#x5217;&#x8868;</a>
          </li>
          <li><a href="#%E8%AE%BE%E7%BD%AE">&#x8BBE;&#x7F6E;</a>
            <ul>
              <li><a href="#%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%88%97%E8%A1%A8">&#x670D;&#x52A1;&#x5668;&#x5217;&#x8868;</a>
              </li>
              <li><a href="#%E9%80%89%E9%A1%B9%E9%A1%B5">&#x9009;&#x9879;&#x9875;</a></li>
              <li><a
                  href="#%E5%88%B7%E6%96%B0%E8%A7%86%E9%A2%91%E9%A1%B5%E9%9D%A2">&#x5237;&#x65B0;&#x89C6;&#x9891;&#x9875;&#x9762;</a>
              </li>
            </ul>
          </li>
          <li><a href="#%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E">&#x4F7F;&#x7528;&#x8BF4;&#x660E;</a>
            <ul>
              <li><a href="#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9">&#x6CE8;&#x610F;&#x4E8B;&#x9879;</a></li>
              <li><a
                  href="#%E6%89%93%E5%BC%80%E8%A7%86%E9%A2%91%E9%A1%B5%E9%9D%A2">&#x6253;&#x5F00;&#x89C6;&#x9891;&#x9875;&#x9762;</a>
              </li>
              <li><a href="#%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E7%A0%81">&#x83B7;&#x53D6;&#x8FDE;&#x63A5;&#x7801;</a>
              </li>
              <li><a href="#%E5%BC%80%E5%A7%8B%E8%BF%9E%E6%8E%A5">&#x5F00;&#x59CB;&#x8FDE;&#x63A5;</a></li>
              <li><a href="#%E6%84%89%E5%BF%AB%E8%A7%82%E7%9C%8B%E5%90%A7">&#x6109;&#x5FEB;&#x89C2;&#x770B;&#x5427;</a>
              </li>
            </ul>
          </li>
          <li><a href="#vlc%E6%94%AF%E6%8C%81">VLC&#x652F;&#x6301;</a>
            <ul>
              <li><a
                  href="#%E9%80%9A%E8%BF%87web%E6%8E%A7%E5%88%B6%E7%95%8C%E9%9D%A2%E6%93%8D%E6%8E%A7vlc%E6%92%AD%E6%94%BE">&#x901A;&#x8FC7;Web&#x63A7;&#x5236;&#x754C;&#x9762;&#x64CD;&#x63A7;VLC&#x64AD;&#x653E;</a>
              </li>
              <li><a
                  href="#%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E7%A0%81-1">&#x83B7;&#x53D6;&#x8FDE;&#x63A5;&#x7801;</a>
              </li>
              <li><a href="#%E5%BC%80%E5%A7%8B%E8%BF%9E%E6%8E%A5-1">&#x5F00;&#x59CB;&#x8FDE;&#x63A5;</a></li>
              <li><a
                  href="#%E6%84%89%E5%BF%AB%E8%A7%82%E7%9C%8B%E5%90%A7-1">&#x6109;&#x5FEB;&#x89C2;&#x770B;&#x5427;</a>
              </li>
              <li><a
                  href="#%E5%85%B3%E9%97%AD%E6%8E%A7%E5%88%B6%E9%A1%B5%E9%9D%A2">&#x5173;&#x95ED;&#x63A7;&#x5236;&#x9875;&#x9762;</a>
              </li>
            </ul>
          </li>
          <li><a href="#%E5%AE%89%E8%A3%85">&#x5B89;&#x88C5;</a>
            <ul>
              <li><a href="#%E8%B0%B7%E6%AD%8C%E6%B5%8F%E8%A7%88%E5%99%A8">&#x8C37;&#x6B4C;&#x6D4F;&#x89C8;&#x5668;</a>
                <ul>
                  <li><a
                      href="#%E4%BB%8E%E8%B0%B7%E6%AD%8C%E5%95%86%E5%BA%97%E5%AE%89%E8%A3%85">&#x4ECE;&#x8C37;&#x6B4C;&#x5546;&#x5E97;&#x5B89;&#x88C5;</a>
                  </li>
                  <li><a
                      href="#%E4%BB%8E%E6%9C%AC%E5%9C%B0-crx-%E6%96%87%E4%BB%B6%E5%AE%89%E8%A3%85">&#x4ECE;&#x672C;&#x5730;
                      .crx &#x6587;&#x4EF6;&#x5B89;&#x88C5;</a></li>
                  <li><a
                      href="#%E5%AE%89%E8%A3%85%E6%9C%AA%E6%89%93%E5%8C%85%E7%9A%84%E6%8F%92%E4%BB%B6">&#x5B89;&#x88C5;&#x672A;&#x6253;&#x5305;&#x7684;&#x63D2;&#x4EF6;</a>
                  </li>
                </ul>
              </li>
              <li><a
                  href="#%E5%BE%AE%E8%BD%AFedge%E6%B5%8F%E8%A7%88%E5%99%A8">&#x5FAE;&#x8F6F;Edge&#x6D4F;&#x89C8;&#x5668;:</a>
                <ul>
                  <li><a
                      href="#%E4%BB%8Eedge%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8F%92%E4%BB%B6%E4%B8%AD%E5%BF%83%E5%AE%89%E8%A3%85">&#x4ECE;Edge&#x6D4F;&#x89C8;&#x5668;&#x63D2;&#x4EF6;&#x4E2D;&#x5FC3;&#x5B89;&#x88C5;</a>
                  </li>
                </ul>
              </li>
              <li><a
                  href="#firefox%E5%90%8E%E7%BB%AD%E7%89%88%E6%9C%AC%E6%B7%BB%E5%8A%A0%E6%94%AF%E6%8C%81">Firefox&#xFF08;&#x540E;&#x7EED;&#x7248;&#x672C;&#x6DFB;&#x52A0;&#x652F;&#x6301;&#xFF09;</a>
              </li>
            </ul>
          </li>
          <li><a
              href="#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">&#x670D;&#x52A1;&#x7AEF;&#x90E8;&#x7F72;&#x6307;&#x5357;</a>
            <ul>
              <li><a
                  href="#%E7%9B%B4%E6%8E%A5%E9%83%A8%E7%BD%B2%E4%B8%8D%E4%BD%BF%E7%94%A8docker%E5%AE%B9%E5%99%A8">&#x76F4;&#x63A5;&#x90E8;&#x7F72;&#xFF08;&#x4E0D;&#x4F7F;&#x7528;Docker&#x5BB9;&#x5668;&#xFF09;:</a>
              </li>
              <li><a
                  href="#%E4%BD%BF%E7%94%A8docker%E5%AE%B9%E5%99%A8%E9%83%A8%E7%BD%B2">&#x4F7F;&#x7528;Docker&#x5BB9;&#x5668;&#x90E8;&#x7F72;</a>
              </li>
            </ul>
          </li>
          <li><a href="#%E7%89%88%E6%9C%AC%E6%97%A5%E5%BF%97">&#x7248;&#x672C;&#x65E5;&#x5FD7;</a>
            <ul>
              <li><a href="#v107-1">v1.0.7</a></li>
              <li><a href="#v106-1">v1.0.6</a></li>
              <li><a href="#v105-1">v1.0.5</a></li>
              <li><a href="#v104-1">v1.0.4</a></li>
              <li><a href="#v103-1">v1.0.3</a></li>
              <li><a href="#v102-1">v1.0.2</a></li>
              <li><a href="#v001-1">v0.0.1</a></li>
            </ul>
          </li>
          <li><a href="#%E5%BC%80%E5%8F%91%E8%80%85">&#x5F00;&#x53D1;&#x8005;</a></li>
          <li><a href="#%E5%8F%82%E4%B8%8E%E6%9B%B4%E6%96%B0">&#x53C2;&#x4E0E;&#x66F4;&#x65B0;</a></li>
          <li><a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">&#x5E38;&#x89C1;&#x95EE;&#x9898;</a>
            <ul>
              <li><a
                  href="#%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E8%B0%83%E8%AF%95%E4%BF%A1%E6%81%AF">&#x5982;&#x4F55;&#x83B7;&#x53D6;&#x8C03;&#x8BD5;&#x4FE1;&#x606F;</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    <h2 class="mume-header" id="supported-list">Supported list</h2>

    <ul>
      <li><a href="https://www.iqiyi.com/">Iqiyi</a></li>
      <li><a href="https://www.youku.com/">Youku</a></li>
      <li><a href="https://www.weiyun.com/">Tencent Cloud</a></li>
      <li><a href="https://v.qq.com/">Tencent Video</a></li>
      <li><a href="https://www.youtube.com/">YouTube</a></li>
      <li><a href="https://www.mgtv.com/">Mango TV</a></li>
      <li>Local mp4 file via Browser</li>
      <li><a href="https://www.videolan.org/vlc/index.html">Local video file via VLC media player</a></li>
    </ul>
    <p><a href="https://github.com/LouisYLWang/Sync-Sofa/issues/22">Click here to tell us more</a></p>
    <h2 class="mume-header" id="setting">Setting</h2>

    <p>&#x1F60A; This part is optional, we have already set default options for you, if you are not interested, please
      skip to <a href="#usage">next part</a>.</p>
    <h3 class="mume-header" id="server-list">Server list</h3>

    <p>Recently, Many Chinese users said our service is unstable, that is because our default server is located at us,
      so here is the server list, you can pick the nearest one.</p>
    <ul>
      <li>sync-cn:
        <ul>
          <li><code>https</code></li>
          <li><code>sync-cn.onns.xyz</code></li>
        </ul>
      </li>
      <li>sync-cn-2 (Thanks to <a href="https://github.com/huoranxuanyuan">@huoranxuanyuan</a>):
        <ul>
          <li><code>https</code></li>
          <li><code>api.huoranxuanyuan.cn</code></li>
        </ul>
      </li>
      <li>sync-us:
        <ul>
          <li><code>https</code></li>
          <li><code>app.ylwang.me</code></li>
        </ul>
      </li>
    </ul>
    <p>Before setting, check server status here: <a
        href="https://sync-status.onns.xyz/">https://sync-status.onns.xyz/</a>.</p>
    <p>We will be grateful for supporting us to build more server, if it is convenient (Cause this project is
      unprofitable).</p>
    <p><strong>Alipay, Wechat pay, Paypal</strong></p>
    <p><img src="https://onns.xyz/blog/image/20200704-1.png" alt="alipay"> <img
        src="https://onns.xyz/blog/image/20200704-2.png" alt="wechat pay"> <img
        src="https://onns.xyz/blog/image/20200704-3.jpg" alt="paypal"></p>
    <p>If you have already built your own server, and wanna share, please tell us!</p>
    <h3 class="mume-header" id="options-page">Options page</h3>

    <p>There are two ways to visit options page.</p>
    <ol>
      <li>Right click <code>Sync Sofa</code> extension, choose <code>Options</code>.</li>
      <li>Left click <code>Sync Sofa</code> extension, choose <code>Setting</code> icon in popup page.</li>
    </ol>
    <p>Your webpage should be like this:</p>
    <p><img src="https://onns.xyz/blog/image/20200629-3.png" alt="Sync Sofa - Options"></p>
    <h3 class="mume-header" id="refresh-video-page">Refresh video page</h3>

    <p>After saving options, please also refresh the video page or local mp4 page or <a
        href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a> to make changes work.</p>
    <h2 class="mume-header" id="usage">Usage</h2>

    <h3 class="mume-header" id="notices">Notices</h3>

    <p>&#x26A0;&#xFE0F; Before use, please make sure <code>the version number</code> of two clients are consistent.</p>
    <p>&#x26A0;&#xFE0F; Before use, please make sure <code>the server host</code> of two clients are consistent.</p>
    <p>&#x26A0;&#xFE0F; If you want to play local <code>.mp4</code> file, please enable
      <code>Allow access to file URLs</code> in extension details page.</p>
    <ol>
      <li>Open <code>chrome://extensions/</code>, find <code>Sync Sofa</code>, click <code>Details</code> button, enable
        <code>Allow access to file URLs</code>.</li>
      <li>Right click <code>Sync Sofa</code> extension, choose <code>Manage Extensions</code>, enable
        <code>Allow access to file URLs</code>.</li>
    </ol>
    <p>&#x26A0;&#xFE0F; If there are <code>multiple versions</code> of extensions in your browser, please enable one and
      disable others.</p>
    <h3 class="mume-header" id="open-a-video-page">Open a video page</h3>

    <p>You two don&apos;t have to open the same webpage, you play the video via local <code>.mp4</code> file and your
      partner watch it one some video websites, is ok as long as you both watch the same video actually (source
      providers are different).</p>
    <p>In this doc, for example, <code>User A</code> will watch the video on Bilibili and <code>User B</code> will do it
      on Youtube. Here is the webpage:</p>
    <ul>
      <li><a href="https://www.bilibili.com/video/BV1k5411Y7Rc">https://www.bilibili.com/video/BV1k5411Y7Rc</a></li>
      <li><a href="https://www.youtube.com/watch?v=QAelMP1PoNA">https://www.youtube.com/watch?v=QAelMP1PoNA</a></li>
    </ul>
    <p>PS: I&apos;m a fan of Boki, and screenshots have been Gaussian blurred. If there is copyright infringement,
      please contact us to delete.</p>
    <p><img src="https://onns.xyz/blog/image/20200627-1.png" alt="User A"><br>
      <img src="https://onns.xyz/blog/image/20200627-2.png" alt="User B"></p>
    <p>If there are any ads before the video, watch them before the next step.</p>
    <h3 class="mume-header" id="request-new-code">Request new code</h3>

    <p>Click the <code>Sync Sofa</code> extension and then click <code>REQUEST NEW CODE</code> button.</p>
    <p><img src="https://onns.xyz/blog/image/20200627-3.png" alt="User A"></p>
    <p>If nothing goes wrong you will receive a message like
      <code>Room created and room code copied to clipboard</code>, and the <code>room code</code> has been copied to
      your clipboard, send it to your partner.</p>
    <h3 class="mume-header" id="start-connection">Start connection</h3>

    <p>Your partner receives the <code>room code</code>, click the <code>Sync Sofa</code> extension, paste it in the
      input area and click <code>START</code> button.</p>
    <p><img src="https://onns.xyz/blog/image/20200627-4.png" alt="User B"></p>
    <h3 class="mume-header" id="enjoy-yourselves">Enjoy yourselves</h3>

    <p><img src="https://onns.xyz/blog/image/20200627-5.png" alt="User A"><br>
      <img src="https://onns.xyz/blog/image/20200627-6.png" alt="User B"></p>
    <p>Now you can play the video, your operations will be synced to your partner. Enjoy yourselves!</p>
    <h2 class="mume-header" id="vlc-support">VLC support</h2>

    <p>If you and your partner play video via <code>VLC media player</code>, <code>Sync Sofa</code> can also synchronize
      your operations.</p>
    <h3 class="mume-header" id="start-vlc-on-the-server-with-the-web-interface">Start VLC on the server with the Web
      Interface</h3>

    <p>First we need to enable controlling VLC via our browser, here is the official documentation:</p>
    <ul>
      <li><a href="https://wiki.videolan.org/Control_VLC_via_a_browser/">Control VLC via a browser</a></li>
      <li><a href="https://wiki.videolan.org/Documentation:Modules/http_intf/#VLC_2.0.0_and_later">Start VLC on the
          server with the Web Interface</a></li>
    </ul>
    <ol>
      <li>Open VLC media player</li>
      <li>Go
        <code>Tools &#x2192; Preferences (select &quot;All&quot; radio-button) &#x2192; Interface &#x2192; Main interfaces</code>,
        check &quot;Web&quot;<br>
        <img src="https://onns.xyz/blog/image/20200628-1.png" alt="Step 2"></li>
      <li>Go
        <code>Tools &#x2192; Preferences (select &quot;All&quot; radio-button) &#x2192; Interface &#x2192; Main interfaces &#x2192; Lua</code>,
        set <code>Lua HTTP - Password</code><br>
        <img src="https://onns.xyz/blog/image/20200628-2.png" alt="Step 3"></li>
      <li><code>Save</code> and <code>reopen</code> VLC media player</li>
      <li>Open <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a> in your browser</li>
    </ol>
    <p>Your webpage should be like this:</p>
    <p><img src="https://onns.xyz/blog/image/20200628-3.png" alt="VLC media player - Web Interface"></p>
    <h3 class="mume-header" id="request-new-code-1">Request new code</h3>

    <p>Open <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>, click the <code>Sync Sofa</code> extension and
      then click <code>REQUEST NEW CODE</code> button.</p>
    <p>If nothing goes wrong you will receive a message like
      <code>Room created and room code copied to clipboard</code>, and the <code>room code</code> has been copied to
      your clipboard, send it to your partner.</p>
    <h3 class="mume-header" id="start-connection-1">Start connection</h3>

    <p>Your partner receives the <code>room code</code>, click the <code>Sync Sofa</code> extension, paste it in the
      input area and click <code>START</code> button.</p>
    <h3 class="mume-header" id="enjoy-yourselves-1">Enjoy yourselves</h3>

    <p>Now you can play the video, your operations will be synced to your partner. Enjoy yourselves!</p>
    <p><strong>Notice</strong>:</p>
    <p>&#x26A0;&#xFE0F; Keep your browser open and <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a> itself.
    </p>
    <h3 class="mume-header" id="close-controller-webpage">Close Controller webpage</h3>

    <p>After your video is finished, please click <code>STOP</code> button on <code>Sync Sofa</code> extension manually
      or just close <a href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>.</p>
    <h2 class="mume-header" id="installation">Installation</h2>

    <h3 class="mume-header" id="google-chrome">Google Chrome</h3>

    <h4 class="mume-header" id="install-from-chrome-web-store">Install from Chrome Web Store</h4>

    <ol>
      <li>Open <a
          href="https://chrome.google.com/webstore/detail/sync-sofa-online-video-sy/kgpnhgmpijhpkefpddoehhminpfiddmg">Sync
          Sofa - Online Video Synchronizer - Chrome Web Store</a> in your Chrome</li>
      <li>Click <code>Add to Chrome</code> button</li>
      <li>Choose <code>Add extension</code></li>
    </ol>
    <h4 class="mume-header" id="install-from-local-crx-file">Install from local .crx file</h4>

    <ol>
      <li>Open <a href="https://github.com/LouisYLWang/Sync-Sofa/releases/latest">Github release page</a></li>
      <li>Download <code>sync_sofa.[version].crx</code>, <em>[version]</em> is the number of the latest version</li>
      <li>Open <code>chrome://extensions/</code> in your Chrome</li>
      <li>Turn on <code>Developer mode</code> (in the top right corner)</li>
      <li>Drag <code>sync_sofa.[version].crx</code> into the <code>chrome://extensions/</code> page</li>
      <li>Choose <code>Add extension</code></li>
    </ol>
    <p><strong>Notices</strong>:<br>
      If the extension is disabled by Chrome, try <a href="#install-from-chrome-web-store">Install from chrome web
        store</a> or <a href="#install-from-unpackaged-folder">Install from unpackaged folder</a>.</p>
    <blockquote>
      <p>This extension is not listed in the Chrome Web Store and may have been added without your knowledge.</p>
    </blockquote>
    <h4 class="mume-header" id="install-from-unpackaged-folder">Install from unpackaged folder</h4>

    <ol>
      <li>Download <a href="https://github.com/LouisYLWang/Sync-Sofa/archive/master.zip">stable version</a> or <a
          href="https://github.com/LouisYLWang/Sync-Sofa/archive/dev.zip">development version</a> (with new features and
        some bugs maybe)</li>
      <li>Unzip the <code>.zip</code> file you downloaded</li>
      <li>Open <code>chrome://extensions/</code> in your Chrome</li>
      <li>Turn on <code>Developer mode</code> (in the top right corner)</li>
      <li>Click <code>Load unpacked</code> (in the top left corner)</li>
      <li>Choose <code>[download_path]/[unzip folder]/client/chrome_extension</code></li>
      <li>Click <code>select</code></li>
    </ol>
    <h3 class="mume-header" id="microsoft-edge">Microsoft Edge:</h3>

    <h4 class="mume-header" id="install-from-microsoft-edge-addons">Install from Microsoft Edge Addons</h4>

    <ol>
      <li>Open <a href="https://microsoftedge.microsoft.com/addons/detail/kpfbclpafmmjalikjjlcoddffpfgghgp">Sync Sofa -
          Online Video Synchronizer - Microsoft Edge Addons</a> in your Microsoft Edge</li>
      <li>Click <code>Get</code> button</li>
    </ol>
    <h3 class="mume-header" id="firefox-will-be-supported-in-later-version">Firefox (will be supported in later version)
    </h3>

    <h2 class="mume-header" id="self-hosting-guide">Self-hosting Guide</h2>

    <p><strong>Notices</strong>:<br>
      &#x26A0;&#xFE0F; Before hosting, make sure your server can communicate securely with HTTPS and link to an domain
      name. All deploy script are based on Let&apos;s Encrypt certificates, you can customize with your own SSL
      certificate providers.<br>
      &#x26A0;&#xFE0F; dev mode intends for http transmission, prod mode intends for https transmission.</p>
    <h3 class="mume-header" id="without-docker">Without Docker</h3>

    <p><strong>1. Get binary executable file</strong></p>
    <ul>
      <li>
        <p>If you want to alter the source code and build yourself, make sure you have <code>golang environment</code>
          in your server, then run script below to get and build binary file:</p>
        <pre data-role="codeBlock" data-info="shell" class="language-shell">go get github.com/LouisYLWang/Sync-Sofa/server
<span class="token comment"># If you don&apos;t know $GOPATH</span>
<span class="token comment"># try &quot;go env GOPATH&quot;</span>
<span class="token function">cd</span> <span class="token variable">$GOPATH</span>/src/github.com/LouisYLWang/Sync-Sofa/server

<span class="token comment"># Next step is optional</span>
<span class="token comment"># If you have any error message like:</span>
<span class="token comment"># &quot;dial tcp 216.58.200.49:443: i/o timeout&quot;</span>
<span class="token comment"># then try</span>
<span class="token function">export</span> GOPROXY<span class="token operator">=</span>https://goproxy.io

go <span class="token function">install</span>
<span class="token function">cd</span> <span class="token variable">$GOPATH</span>/bin
</pre>
      </li>
      <li>
        <p>If you want to only deploy the binary file:</p>
        <ol>
          <li>Open <a href="https://github.com/LouisYLWang/Sync-Sofa/releases/latest">Github release page</a></li>
          <li>Download <code>server</code> binary file for linux server</li>
          <li>Download <code>config.json</code> file to the same directory of binary file</li>
        </ol>
      </li>
    </ul>
    <p><strong>2. In the directory of binary file, adjust config file base on your need:</strong></p>
    <ul>
      <li>
        <p>Config file variables:</p>
        <ul>
          <li><code>addr</code>: port of server</li>
          <li><code>runmode</code>:
            <ul>
              <li>dev: developing mode</li>
              <li>prod: producting mode</li>
            </ul>
          </li>
          <li><code>tlsdir</code>: TLS certificate paths
            <ul>
              <li><code>tlskey</code>: TLS certificate privatekey path</li>
              <li><code>tlscert</code>: TLS certification path</li>
            </ul>
          </li>
        </ul>
        <p><strong>Notices</strong>: <code>addr</code>, <code>runmode</code> are mandatory, <code>tlskey</code>,
          <code>tlscert</code> are required for TLS connection</p>
      </li>
      <li>
        <p>minimal (non-https) config file:</p>
        <pre data-role="codeBlock" data-info="json" class="language-json"><span class="token punctuation">{</span>
  <span class="token property">&quot;addr&quot;</span><span class="token operator">:</span> <span class="token string">&quot;:80&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;runmode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;dev&quot;</span>
<span class="token punctuation">}</span>
</pre>
      </li>
      <li>
        <p>production environment (https) config file:</p>
        <pre data-role="codeBlock" data-info="json" class="language-json"><span class="token punctuation">{</span>
  <span class="token property">&quot;addr&quot;</span><span class="token operator">:</span> <span class="token string">&quot;:443&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;runmode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;prod&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;tlsdir&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;tlskey&quot;</span><span class="token operator">:</span> <span class="token string">&quot;/etc/letsencrypt/live/your.host.url/privkey.pem&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;tlscert&quot;</span><span class="token operator">:</span> <span class="token string">&quot;/etc/letsencrypt/live/your.host.url/fullchain.pem&quot;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</pre>
      </li>
    </ul>
    <p><strong>3. Run <code>./server</code> to delopy the server, deployment is successful if you see:</strong></p>
    <pre data-role="codeBlock" data-info class="language-"><code>found config file, read parameters from config file...
server is listening at {your_port_number}...
</code></pre>
    <h3 class="mume-header" id="with-docker">With Docker</h3>

    <p>Make sure docker service is runing on your server, make change to the script blow and run:</p>
    <ul>
      <li>
        <p>variables</p>
        <ul>
          <li><code>ADDR</code>: port of server</li>
          <li><code>RUNMODE</code>:
            <ul>
              <li>dev: developing mode</li>
              <li>prod: producting mode</li>
            </ul>
          </li>
          <li><code>APIHOST</code>: your host name</li>
          <li><code>IMGNAME</code>: your docker image name, set arbitrarily</li>
          <li><code>TLSKEYPATH</code>: TLS certificate privatekey path</li>
          <li><code>TLSCERTPATH</code>: TLS certification path</li>
        </ul>
      </li>
      <li>
        <p>minimal (non-https) hosting script:</p>
        <pre data-role="codeBlock" data-info="sh" class="language-bash">docker pull louisylwang/watchtogether

<span class="token function">export</span> ADDR<span class="token operator">=</span>:4000 \      
<span class="token function">export</span> RUNMODE<span class="token operator">=</span>dev \   
<span class="token function">export</span> IMGNAME<span class="token operator">=</span>yourimagename \   

docker run -d \
-e ADDR<span class="token operator">=</span>:4000 \
-e RUNMODE<span class="token operator">=</span>RUNMODE \
-p 4000:4000 \
--name IMGNAME louisylwang/watchtogether
</pre>
      </li>
      <li>
        <p>production environment (https) hosting script:</p>
        <pre data-role="codeBlock" data-info="sh" class="language-bash">docker pull louisylwang/watchtogether

<span class="token function">export</span> ADDR<span class="token operator">=</span>:443 \      
<span class="token function">export</span> RUNMODE<span class="token operator">=</span>prod \   
<span class="token function">export</span> APIHOST<span class="token operator">=</span>your.host.name \   
<span class="token function">export</span> IMGNAME<span class="token operator">=</span>yourimagename \   
<span class="token function">export</span> TLSKEYPATH<span class="token operator">=</span>/your/path/to/TLS/privatekey \
<span class="token function">export</span> TLSCERTPATH<span class="token operator">=</span>/your/path/to/TLS/certification \


docker run -d \
-e ADDR<span class="token operator">=</span>:ADDR \
<span class="token comment">#docker port to server:server port to docker, not necessarily the same</span>
-p ADDR:ADDR \ 
-e RUNMODE<span class="token operator">=</span>RUNMODE \
<span class="token comment">#if you use letsencrypt, TLSKEY value should be /etc/letsencrypt/live/$APIHOST/privkey.pem</span>
-e TLSKEY<span class="token operator">=</span>TLSKEYPATH \ 
<span class="token comment">#if you use letsencrypt, TLSCERT value should be /etc/letsencrypt/live/$APIHOST/fullchain.pem </span>
-e TLSCERT<span class="token operator">=</span>TLSCERTPATH \ 
<span class="token comment">#need to expose your TLS certification file to docker</span>
-v /etc/letsencrypt:/etc/letsencrypt:ro \ 
--name IMGNAME louisylwang/watchtogether \
--restart<span class="token operator">=</span>always
</pre>
      </li>
      <li>
        <p>deployment is successful if you see in <code>docker logs {your docker image name}</code>:</p>
        <pre data-role="codeBlock" data-info class="language-"><code>not found config file, read parameters from system variables...
YYYY/MM/DD HH:MM:SS server is listening at :ADDR...
</code></pre>
      </li>
    </ul>
    <h2 class="mume-header" id="release-history">Release History</h2>

    <h3 class="mume-header" id="v107">v1.0.7</h3>

    <h2>&#x1F6E0; update on 7 July 2020</h2>
    <p>&#x26A0;&#x26A0;&#x26A0; Notice, this version is not compatible with any version before 1.0.6 (&lt;= 1.0.5),
      please please please make sure your version is the same as your peer&apos;s version</p>
    <p>Add:<br>
      add version detection (lower version number will be detected from user with higher version number if room was
      established by lower version extension)</p>
    <p>Fix:<br>
      fix support for <a href="https://www.bilibili.com/bangumi/*">https://www.bilibili.com/bangumi/*</a> (bilibili
      movie)<br>
      fix support for Youku &amp; mangoTV</p>
    <h3 class="mume-header" id="v106">v1.0.6</h3>

    <h2>&#x1F6E0; update on 28 June 2020</h2>
    <p>&#x26A0;&#x26A0;&#x26A0; Notice, this version is not compatible with any version before, please please please
      make sure your version is the same as your peer&apos;s version</p>
    <ul>
      <li>Add:
        <ul>
          <li>add support for Mango TV (happy Sistering &#x1F923;)</li>
          <li>add support for local video file syncing with VLC player #20</li>
          <li>add options page - debugging mode &amp; self-hosting option #21</li>
          <li>add donating page</li>
          <li>add new wiki page #11</li>
        </ul>
      </li>
      <li>Fix:
        <ul>
          <li>improve sync performance &amp; stability:
            <ul>
              <li>new sync logic, not compatible with any version before</li>
              <li>improve buffer detection</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v105">v1.0.5</h3>

    <h2>&#x1F6E0; update on 12 May 2020</h2>
    <p>Improve stability</p>
    <blockquote>
      <p>Test for a new logic to avoid infinite echo back (each party repeat the last operation of other party) :
        introduce a queue as a buffer of operation and if the operations is beyond frequency threshold, the client will
        automatically to halt and cool down for sometime.</p>
    </blockquote>
    <p>Add support for edge browser (beta)</p>
    <h3 class="mume-header" id="v104">v1.0.4</h3>

    <h2>&#x1F6E0; update on 10 May 2020</h2>
    <p>Now user will get notification when they successfully connected to each other<br>
      Improve stability, better sync performance<br>
      Change the notification UI using sweetalert</p>
    <h3 class="mume-header" id="v103">v1.0.3</h3>

    <h2>&#x1F6E0; update on 8 May 2020</h2>
    <p>improve stability &amp; UX logic<br>
      Added support of following websites:</p>
    <ul>
      <li><a href="https://www.iqiyi.com/">iqiyi</a></li>
      <li><a href="https://www.youku.com/">youku</a></li>
      <li><a href="https://www.weiyun.com/">weiyun</a></li>
      <li><a href="https://v.qq.com/">tencent video</a></li>
    </ul>
    <p>Fixed the support of duonao live;<br>
      Removed the support of 91mjw (temporarily);<br>
      Refined documentation, will add more detail in next verison;</p>
    <h3 class="mume-header" id="v102">v1.0.2</h3>

    <h2>&#x1F6E0; update on 31 Mar 2020</h2>
    <p>Add support of play process bar control sync<br>
      Fixed the issue that when syncing playing time, there is the possibility to crash the extension</p>
    <h3 class="mume-header" id="v001">v0.0.1</h3>

    <h2>&#x1F6E0; update on 26 Mar 2020 (beta version)</h2>
    <p>Add support of 2 parties connection<br>
      Add support of sync pause and play action<br>
      Add support of out-of-sync notification</p>
    <h2 class="mume-header" id="meta">Meta</h2>

    <p>Yiliang &quot;Louis&quot; Wang &#x2013; <a href="https://ylwang.codes/">@blog</a> &#x2013; <a
        href="mailto:louis.yl.wang@outlook.com">@mail</a></p>
    <p>Onns &#x2013; <a href="https://onns.xyz/">@blog</a> &#x2013; <a href="mailto:onns@onns.xyz">@mail</a></p>
    <h2 class="mume-header" id="contributing">Contributing</h2>

    <ol>
      <li>Fork it (<a
          href="https://github.com/LouisYLWang/Sync-Sofa/fork">https://github.com/LouisYLWang/Sync-Sofa/fork</a>)</li>
      <li>Create your feature branch (<code>git checkout -b feature/fooBar</code>)</li>
      <li>Commit your changes (<code>git commit -am &apos;Add some fooBar&apos;</code>)</li>
      <li>Push to the branch (<code>git push origin feature/fooBar</code>)</li>
      <li>Create a new Pull Request</li>
    </ol>
    <h2 class="mume-header" id="faq">FAQ</h2>

    <ol>
      <li>
        <p><strong>Q:</strong> When I installed, Chrome popup says that Sync Sofa requires the permissions of
          <code>read and change your data on a number of websites</code> and <code>read your browsing history</code>,
          sounds so horrible, is that safe?<br>
          <strong>A:</strong> We do not collect your browsing data, the only thing we do is to get your current tab
          information and make sure you are visiting a site we support (<a href="#supported-list">support list</a>). All
          information is collected and processed locally. We do not mess up the data on the websites you are watching,
          just inject a sync script to get your pause, play and seek operation. <strong>All source code can be reviewed
            at <a href="https://github.com/LouisYLWang/Sync-Sofa">our github page</a>, we promise everything we did is
            necessary and not harmful.</strong></p>
      </li>
      <li>
        <p>If your find your extension <strong>button is darken</strong>, please first make sure you are in a video
          playing page.</p>
      </li>
      <li>
        <p>If you find your extension <strong>can not request room code</strong>, please first check the <a
            href="#options-page">option page</a> and click <code>RESET</code> button. If it still not work, please close
          your web browser, wait for a while and try again. Currently our server is hosting abroad, it may cause
          connecting issue.</p>
      </li>
      <li>
        <p>If you find your extension cannot connect to your peer, please check following:</p>
        <ol>
          <li>please make sure the <strong>version number</strong> of two clients are consistent. To check the version
            number, you need to open <a href="chrome://extensions/">chrome extension page</a> (if this link is not work,
            please type <code>chrome://extensions/</code> into the address bar and visit). You will find a extension
            with the title of <code>Sync Sofa - Online Video Synchronizer 1.0.6</code>. <code>1.0.6</code> is your
            current version number of Sync Sofa.</li>
          <li>If 4.1 does not solve your problem, please try step 2 again.</li>
        </ol>
      </li>
    </ol>
    <h3 class="mume-header" id="how-to-get-debug-info">How to get debug info</h3>

    <ol>
      <li>Open <code>Debug mode</code> in <a href="#options-page">Options page</a>.</li>
      <li>Refresh video page (to make changes work).</li>
      <li><code>Shift + ctrl + i</code> in Windows or <code>Shift + cmd + i</code> in MacOS.</li>
      <li>Choose <code>console</code> tab.</li>
    </ol>
    <h1 class="mume-header"
      id="sync-sofa-%E5%9C%A8%E7%BA%BF%E8%A7%86%E9%A2%91%E5%90%8C%E6%AD%A5%E6%92%AD%E6%94%BE%E6%8F%92%E4%BB%B6">Sync
      Sofa &#xFF08;&#x5728;&#x7EBF;&#x89C6;&#x9891;&#x540C;&#x6B65;&#x64AD;&#x653E;&#x63D2;&#x4EF6;&#xFF09;</h1>

    <blockquote>
      <p>
        &#x4EE5;&#x7A33;&#x5B9A;&#xFF0C;&#x5FEB;&#x6377;&#x7684;&#x65B9;&#x5F0F;&#x8FDC;&#x7A0B;&#x540C;&#x6B65;&#x89C2;&#x770B;&#x5728;&#x7EBF;/&#x672C;&#x5730;&#x89C6;&#x9891;
      </p>
    </blockquote>
    <p><img
        src="https://img.shields.io/github/go-mod/go-version/LouisYLWang/Sync-Sofa?filename=server%2Fgo.mod&amp;style=flat-square"
        alt="GitHub go.mod Go version (subfolder of monorepo)"> <a
        href="https://chrome.google.com/webstore/detail/sync-sofa-beta-online-vid/kgpnhgmpijhpkefpddoehhminpfiddmg"><img
          src="https://img.shields.io/chrome-web-store/users/kgpnhgmpijhpkefpddoehhminpfiddmg?style=flat-square"
          alt="Chrome web store users"></a></p>
    <p>Sync
      Sofa&#x662F;&#x4E00;&#x4E2A;&#x7A33;&#x5B9A;&#x6613;&#x7528;&#x7684;Chrome&#x6D4F;&#x89C8;&#x5668;&#x62D3;&#x5C55;&#x63D2;&#x4EF6;&#xFF0C;&#x53EF;&#x540C;&#x6B65;&#x4E24;&#x7AEF;&#x7528;&#x6237;&#x7684;&#x89C6;&#x9891;&#x64AD;&#x653E;&#x64CD;&#x4F5C;&#xFF0C;&#x63D0;&#x9AD8;&#x4E0E;&#x8EAB;&#x5904;&#x5F02;&#x5730;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x4E00;&#x540C;&#x89C2;&#x770B;&#x89C6;&#x9891;&#x7684;&#x4F53;&#x9A8C;&#xFF0C;&#x76EE;&#x524D;&#x652F;&#x6301;&#x4EE5;&#x4E0B;&#x4E3B;&#x8981;&#x529F;&#x80FD;&#xFF1A;
    </p>
    <ul>
      <li>
        &#x5E73;&#x7B49;&#x53CC;&#x4EBA;&#x8FDE;&#x63A5;&#xFF1A;&#x4EFB;&#x610F;&#x4E00;&#x7AEF;&#x5747;&#x53EF;&#x63A7;&#x5236;&#x5BF9;&#x65B9;&#x64AD;&#x653E;&#x72B6;&#x6001;
      </li>
      <li>
        &#x540C;&#x6B65;&#x64AD;&#x653E;&#x8FDB;&#x5EA6;&#xFF1A;&#x652F;&#x6301;&#x64AD;&#x653E;&#x3001;&#x6682;&#x505C;&#x3001;&#x8FDB;&#x5EA6;&#x5207;&#x6362;&#x7B49;&#x64CD;&#x4F5C;
      </li>
      <li>
        &#x672C;&#x5730;&#x89C6;&#x9891;&#x540C;&#x6B65;&#xFF1A;&#x53EF;&#x901A;&#x8FC7;VLC&#x540C;&#x6B65;&#x672C;&#x5730;&#x89C6;&#x9891;&#x64AD;&#x653E;&#x72B6;&#x6001;
      </li>
    </ul>
    <h2 class="mume-header" id="%E5%BD%93%E5%89%8D%E7%89%88%E6%9C%AC%E7%89%B9%E6%80%A7">
      &#x5F53;&#x524D;&#x7248;&#x672C;&#x7279;&#x6027;:</h2>

    <p><strong>v1.0.7 - 2020&#x5E74;7&#x6708;5&#x65E5;&#x66F4;&#x65B0;</strong></p>
    <p>&#x26A0;&#x26A0;&#x26A0; &#x6CE8;&#x610F;&#xFF0C;&#x6B64;&#x7248;&#x672C;&#x4E0E;&lt;=
      1.0.5&#x7684;&#x4EFB;&#x4F55;&#x7248;&#x672C;&#x90FD;&#x4E0D;&#x517C;&#x5BB9;&#xFF0C;&#x8BF7;&#x52A1;&#x5FC5;&#x786E;&#x4FDD;&#x4F60;&#x7684;&#x7248;&#x672C;&#x4E0E;&#x5C0F;&#x4F19;&#x4F34;&#x7684;&#x7248;&#x672C;&#x4E00;&#x81F4;&#x3002;
    </p>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>
            &#x65B0;&#x589E;&#x7248;&#x672C;&#x68C0;&#x6D4B;&#xFF08;&#x9AD8;&#x7248;&#x672C;&#x7528;&#x6237;&#x4E0E;&#x4F4E;&#x7248;&#x672C;&#x7528;&#x6237;&#x8FDE;&#x63A5;&#x65F6;&#xFF0C;&#x82E5;&#x8FDE;&#x63A5;&#x7801;&#x7531;&#x4F4E;&#x7248;&#x672C;&#x7528;&#x6237;&#x7533;&#x8BF7;&#xFF0C;&#x9AD8;&#x7248;&#x672C;&#x7528;&#x6237;&#x5C06;&#x6536;&#x5230;&#x63D0;&#x793A;&#xFF0C;&#x8BF7;&#x6839;&#x636E;&#x63D0;&#x793A;&#x544A;&#x77E5;&#x5BF9;&#x65B9;&#x5347;&#x7EA7;&#x6700;&#x65B0;&#x7248;&#x672C;&#xFF09;
          </li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;:
        <ul>
          <li>&#x4FEE;&#x590D;&#x5BF9; <a href="https://www.bilibili.com/bangumi/*">bilibili movie</a>
            &#x7684;&#x652F;&#x6301;</li>
          <li>
            &#x4FEE;&#x590D;&#x4E86;&#x4F18;&#x9177;&#x53CA;&#x8292;&#x679C;TV&#x65E0;&#x6CD5;&#x540C;&#x6B65;&#x64CD;&#x4F5C;&#x7684;&#x95EE;&#x9898;
          </li>
        </ul>
      </li>
    </ul>
    <hr>
    <h2 class="mume-header" id="%E6%94%AF%E6%8C%81%E7%BD%91%E7%AB%99%E5%88%97%E8%A1%A8">
      &#x652F;&#x6301;&#x7F51;&#x7AD9;&#x5217;&#x8868;</h2>

    <ul>
      <li><a href="https://www.iqiyi.com/">&#x7231;&#x5947;&#x827A;</a></li>
      <li><a href="https://www.youku.com/">&#x4F18;&#x9177;</a></li>
      <li><a href="https://www.weiyun.com/">&#x5FAE;&#x4E91;</a></li>
      <li><a href="https://v.qq.com/">&#x817E;&#x8BAF;&#x89C6;&#x9891;</a></li>
      <li><a href="https://www.youtube.com/">&#x6CB9;&#x7BA1;</a></li>
      <li><a href="https://www.mgtv.com/">&#x8292;&#x679C;</a></li>
      <li>
        &#x901A;&#x8FC7;&#x6D4F;&#x89C8;&#x5668;&#x64AD;&#x653E;&#x672C;&#x5730;&#x89C6;&#x9891;&#xFF08;&#x4EC5;&#x652F;&#x6301;AVC/H.264&#x7F16;&#x7801;&#xFF09;
      </li>
      <li><a
          href="https://www.videolan.org/vlc/index.html">&#x901A;&#x8FC7;VLC&#x89C6;&#x9891;&#x64AD;&#x653E;&#x5668;&#x64AD;&#x653E;&#x672C;&#x5730;&#x89C6;&#x9891;</a>
      </li>
    </ul>
    <p><a
        href="https://github.com/LouisYLWang/Sync-Sofa/issues/22">&#x70B9;&#x51FB;&#x8FD9;&#x91CC;&#x5411;&#x6211;&#x4EEC;&#x53CD;&#x9988;&#x66F4;&#x591A;&#x7F51;&#x7AD9;</a>
    </p>
    <h2 class="mume-header" id="%E8%AE%BE%E7%BD%AE">&#x8BBE;&#x7F6E;</h2>

    <p>&#x1F60A;
      &#x6B64;&#x90E8;&#x5206;&#x4E3A;&#x53EF;&#x9009;&#x8BBE;&#x7F6E;&#xFF0C;&#x6211;&#x4EEC;&#x5DF2;&#x7ECF;&#x4E3A;&#x4F60;&#x914D;&#x7F6E;&#x597D;&#x9ED8;&#x8BA4;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x4E0D;&#x611F;&#x5174;&#x8DA3;&#xFF0C;&#x6216;&#x8005;&#x6CA1;&#x6709;&#x4FEE;&#x6539;&#x670D;&#x52A1;&#x5668;&#x7684;&#x9700;&#x6C42;&#xFF0C;&#x8BF7;&#x79FB;&#x6B65;&#x81F3;<a
        href="#usage">&#x4E0B;&#x4E00;&#x90E8;&#x5206;</a>.</p>
    <h3 class="mume-header" id="%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%88%97%E8%A1%A8">&#x670D;&#x52A1;&#x5668;&#x5217;&#x8868;
    </h3>

    <p>
      &#x6700;&#x8FD1;&#x8BB8;&#x591A;&#x7528;&#x6237;&#x53CD;&#x6620;&#x56FD;&#x5185;&#x7684;&#x8BBF;&#x95EE;&#x4E0D;&#x7A33;&#x5B9A;&#xFF0C;&#x662F;&#x56E0;&#x4E3A;&#x6211;&#x4EEC;&#x7684;&#x9ED8;&#x8BA4;&#x670D;&#x52A1;&#x5668;&#x5728;&#x7F8E;&#x56FD;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x4EEC;&#x63D0;&#x4F9B;&#x4E86;&#x5907;&#x7528;&#x670D;&#x52A1;&#x5668;&#x5217;&#x8868;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x4F60;&#x7684;&#x4F4D;&#x7F6E;&#x5207;&#x6362;&#x5230;&#x79BB;&#x4F60;&#x8DDD;&#x79BB;&#x66F4;&#x8FD1;&#x7684;&#x670D;&#x52A1;&#x5668;&#x3002;
    </p>
    <ul>
      <li>&#x4E2D;&#x56FD;&#x676D;&#x5DDE;:
        <ul>
          <li><code>https</code></li>
          <li><code>sync-cn.onns.xyz</code></li>
        </ul>
      </li>
      <li>&#x4E2D;&#x56FD;&#x5317;&#x4EAC; (&#x611F;&#x8C22; <a
          href="https://github.com/huoranxuanyuan">@huoranxuanyuan</a>):
        <ul>
          <li><code>https</code></li>
          <li><code>api.huoranxuanyuan.cn</code></li>
        </ul>
      </li>
      <li>&#x7F8E;&#x56FD;:
        <ul>
          <li><code>https</code></li>
          <li><code>app.ylwang.me</code></li>
        </ul>
      </li>
    </ul>
    <p>
      &#x5728;&#x8BBE;&#x7F6E;&#x670D;&#x52A1;&#x5668;&#x524D;&#xFF0C;&#x8BF7;&#x68C0;&#x67E5;&#x670D;&#x52A1;&#x5668;&#x7684;&#x72B6;&#x6001;&#xFF1A;<a
        href="https://sync-status.onns.xyz/">https://sync-status.onns.xyz/</a>.</p>
    <p>
      &#x6211;&#x4EEC;&#x4F1A;&#x611F;&#x8C22;&#x4F60;&#x5BF9;&#x8BE5;&#x5F00;&#x6E90;&#x9879;&#x76EE;&#x4F5C;&#x51FA;&#x7684;&#x8D21;&#x732E;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<strong>&#x63D0;&#x4F9B;&#x81EA;&#x5DF1;&#x90E8;&#x7F72;&#x7684;&#x670D;&#x52A1;</strong>&#x6765;&#x652F;&#x6301;&#x6211;&#x4EEC;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x5E2E;&#x6211;&#x4EEC;<strong>&#x5206;&#x62C5;&#x4E00;&#x70B9;&#x670D;&#x52A1;&#x5668;&#x8D39;&#x7528;</strong>&#x7684;&#x538B;&#x529B;&#x3002;&#xFF08;<s>&#x4E5F;&#x53EF;&#x4EE5;&#x4E00;&#x952E;&#x4E09;&#x8FDE;</s>&#xFF09;
    </p>
    <p><strong>&#x652F;&#x4ED8;&#x5B9D;, &#x5FAE;&#x4FE1;&#x652F;&#x4ED8;, &#x8D1D;&#x5B9D;</strong></p>
    <p><img src="https://onns.xyz/blog/image/20200704-1.png" alt="alipay"> <img
        src="https://onns.xyz/blog/image/20200704-2.png" alt="wechat pay"> <img
        src="https://onns.xyz/blog/image/20200704-3.jpg" alt="paypal"></p>
    <h3 class="mume-header" id="%E9%80%89%E9%A1%B9%E9%A1%B5">&#x9009;&#x9879;&#x9875;</h3>

    <p>&#x6253;&#x5F00;&#x9009;&#x9879;&#x9875;&#x6709;&#x4E0B;&#x5217;&#x4E24;&#x79CD;&#x65B9;&#x6CD5;&#xFF1A;</p>
    <ol>
      <li>&#x53F3;&#x952E;&#x70B9;&#x51FB;<code>Sync Sofa</code>&#x63D2;&#x4EF6;&#x56FE;&#x6807;,
        &#x9009;&#x62E9;<code>&#x9009;&#x9879;</code>&#x3002;</li>
      <li>&#x5DE6;&#x952E;&#x70B9;&#x51FB;<code>Sync Sofa</code>&#x63D2;&#x4EF6;&#x56FE;&#x6807;,
        &#x5728;&#x63D2;&#x4EF6;&#x5F39;&#x7A97;&#x4E2D;&#x9009;&#x62E9;&#x5E95;&#x90E8;<code>&#x8BBE;&#x7F6E;</code>&#x56FE;&#x6807;&#x3002;
      </li>
    </ol>
    <p>&#x8BBE;&#x7F6E;&#x754C;&#x9762;&#x5982;&#x4E0B;&#xFF1A;</p>
    <p><img src="https://onns.xyz/blog/image/20200629-3.png" alt="Sync Sofa - Options"></p>
    <h3 class="mume-header" id="%E5%88%B7%E6%96%B0%E8%A7%86%E9%A2%91%E9%A1%B5%E9%9D%A2">
      &#x5237;&#x65B0;&#x89C6;&#x9891;&#x9875;&#x9762;</h3>

    <p>
      &#x4FEE;&#x6539;&#x8BBE;&#x7F6E;&#x5E76;&#x4FDD;&#x5B58;&#x540E;&#xFF0C;&#x8BF7;&#x5237;&#x65B0;&#x89C6;&#x9891;&#x7F51;&#x7AD9;&#x9875;&#x9762;/&#x672C;&#x5730;&#x89C6;&#x9891;&#x9875;&#x9762;/
      <a
        href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>&#xFF08;&#x5982;&#x679C;&#x4F60;&#x4F7F;&#x7528;VLC&#x64AD;&#x653E;&#x672C;&#x5730;&#x89C6;&#x9891;&#xFF09;&#x6765;&#x4F7F;&#x8BBE;&#x7F6E;&#x751F;&#x6548;&#x3002;
    </p>
    <h2 class="mume-header" id="%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E">&#x4F7F;&#x7528;&#x8BF4;&#x660E;</h2>

    <h3 class="mume-header" id="%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9">&#x6CE8;&#x610F;&#x4E8B;&#x9879;</h3>

    <p>&#x26A0;&#xFE0F;
      &#x4F7F;&#x7528;&#x524D;&#x8BF7;&#x786E;&#x4FDD;&#x4E24;&#x4E2A;<code>&#x5BA2;&#x6237;&#x7AEF;&#x7248;&#x672C;&#x53F7;</code>&#x4E00;&#x81F4;&#x3002;
    </p>
    <p>&#x26A0;&#xFE0F;
      &#x4F7F;&#x7528;&#x524D;&#x8BF7;&#x786E;&#x4FDD;&#x4E24;&#x4E2A;<code>&#x670D;&#x52A1;&#x5668;&#x57DF;&#x540D;</code>&#x4E00;&#x81F4;&#x3002;
    </p>
    <p>&#x26A0;&#xFE0F;
      &#x5982;&#x9700;&#x64AD;&#x653E;&#x672C;&#x5730;<code>.mp4</code>&#x6587;&#x4EF6;&#xFF0C;&#x8BF7;&#x5728;&#x6269;&#x5C55;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#x9875;&#x9762;&#x542F;&#x7528;&#x201C;&#x5141;&#x8BB8;&#x8BBF;&#x95EE;&#x6587;&#x4EF6;url&#x201D;&#x3002;
    </p>
    <p>&#x65B9;&#x6CD5;1.
      &#x5728;&#x5730;&#x5740;&#x680F;&#x8F93;&#x5165;<code>chrome://extensions/</code>&#xFF0C;&#x627E;&#x5230;<code>Sync Sofa</code>&#xFF0C;&#x70B9;&#x51FB;<code>&#x8BE6;&#x60C5;</code>&#x6309;&#x94AE;&#xFF0C;&#x542F;&#x7528;<code>&#x5141;&#x8BB8;&#x8BBF;&#x95EE;&#x6587;&#x4EF6;&#x7F51;&#x5740;</code>&#x3002;
    </p>
    <p>
      &#x65B9;&#x6CD5;2.&#x53F3;&#x51FB;&#x6D4F;&#x89C8;&#x5668;&#x5DE6;&#x4E0A;&#x89D2;<code>Sync Sofa</code>&#x56FE;&#x6807;&#xFF0C;&#x9009;&#x62E9;<code>&#x7BA1;&#x7406;&#x62D3;&#x5C55;&#x7A0B;&#x5E8F;</code>,
      &#x542F;&#x7528;<code>&#x5141;&#x8BB8;&#x8BBF;&#x95EE;&#x6587;&#x4EF6;&#x7F51;&#x5740;</code>&#x3002;</p>
    <p>&#x26A0;&#xFE0F;
      &#x5982;&#x679C;&#x4F60;&#x7684;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x5B89;&#x88C5;&#x4E86;<code>&#x591A;&#x4E2A;&#x4E0D;&#x540C;&#x7248;&#x672C;</code>&#x7684;<code>Sync Sofa</code>,&#x8BF7;&#x53EA;&#x542F;&#x7528;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x5E76;&#x7981;&#x7528;&#x5176;&#x4ED6;&#x7248;&#x672C;&#x3002;
    </p>
    <h3 class="mume-header" id="%E6%89%93%E5%BC%80%E8%A7%86%E9%A2%91%E9%A1%B5%E9%9D%A2">
      &#x6253;&#x5F00;&#x89C6;&#x9891;&#x9875;&#x9762;</h3>

    <p>
      &#x4F60;&#x4EEC;&#x53EF;&#x4EE5;&#x540C;&#x6B65;&#x89C2;&#x770B;&#x4E0D;&#x540C;&#x6765;&#x6E90;&#x7684;&#x89C6;&#x9891;&#xFF0C;&#x5728;&#x64AD;&#x653E;&#x672C;&#x5730;<code>.mp4</code>&#x89C6;&#x9891;&#x6587;&#x4EF6;&#x65F6;&#xFF0C;&#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x5728;&#x89C6;&#x9891;&#x7F51;&#x7AD9;&#x4E0A;&#x548C;&#x4F60;&#x540C;&#x6B65;&#x89C2;&#x770B;&#xFF0C;&#x6B64;&#x5916;&#xFF0C;&#x4F60;&#x4EEC;&#x8FD8;&#x53EF;&#x4EE5;&#x5728;&#x4E0D;&#x540C;&#x7684;&#x89C6;&#x9891;&#x7F51;&#x7AD9;&#x770B;&#x89C2;&#x770B;&#x76F8;&#x540C;&#x7684;&#x89C6;&#x9891;&#x3002;
    </p>
    <p>
      &#x4F8B;&#x5982;&#xFF0C;<code>&#x7528;&#x6237;A</code>&#x5728;Bilibili&#x4E0A;&#x89C2;&#x770B;&#x6B64;&#x89C6;&#x9891;&#xFF1A;
    </p>
    <ul>
      <li><a href="https://www.bilibili.com/video/BV1k5411Y7Rc">https://www.bilibili.com/video/BV1k5411Y7Rc</a><br>
        <img src="https://onns.xyz/blog/image/20200627-1.png" alt="User A"></li>
    </ul>
    <p>
      &#x6B64;&#x65F6;<code>&#x7528;&#x6237;B</code>&#x53EF;&#x5728;YouTube&#x4E0A;&#x540C;&#x6B65;&#x89C2;&#x770B;&#x540C;&#x4E00;&#x89C6;&#x9891;&#xFF1A;
    </p>
    <ul>
      <li><a href="https://www.youtube.com/watch?v=QAelMP1PoNA">https://www.youtube.com/watch?v=QAelMP1PoNA</a><br>
        <img src="https://onns.xyz/blog/image/20200627-2.png" alt="User B"></li>
    </ul>
    <p>
      PS&#xFF1A;&#x6211;&#x662F;boki&#x7684;&#x7C89;&#x4E1D;&#xFF0C;&#x6240;&#x4EE5;&#x5C31;&#x7528;&#x4E86;&#x5979;&#x7684;&#x89C6;&#x9891;&#x622A;&#x56FE;&#xFF0C;&#x5DF2;&#x7ECF;&#x9AD8;&#x65AF;&#x6A21;&#x7CCA;&#x5904;&#x7406;&#x8FC7;&#x4E86;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x4FB5;&#x6743;&#x7684;&#x8BDD;&#xFF0C;&#x8BF7;&#x8054;&#x7CFB;&#x6211;&#x4EEC;&#x5220;&#x9664;&#xFF0C;&#x771F;&#x7684;&#x5F88;&#x62B1;&#x6B49;&#xFF01;
    </p>
    <p>
      &#x5982;&#x679C;&#x89C6;&#x9891;&#x5F00;&#x59CB;&#x524D;&#x6709;&#x5E7F;&#x544A;&#xFF0C;&#x8BF7;&#x5728;&#x5E7F;&#x544A;&#x7ED3;&#x675F;&#x540E;&#x8FDB;&#x5165;&#x4E0B;&#x4E00;&#x6B65;&#x3002;
    </p>
    <h3 class="mume-header" id="%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E7%A0%81">&#x83B7;&#x53D6;&#x8FDE;&#x63A5;&#x7801;
    </h3>

    <p>&#x70B9;&#x51FB; <code>Sync Sofa</code>
      &#x63D2;&#x4EF6;&#x56FE;&#x6807;&#x5E76;&#x70B9;&#x51FB;<code>REQUEST NEW CODE</code>&#xFF08;&#x83B7;&#x53D6;&#x94FE;&#x63A5;&#x7801;&#xFF09;
      &#x6309;&#x94AE;.</p>
    <p><img src="https://onns.xyz/blog/image/20200627-3.png" alt="User A"></p>
    <p>
      &#x5982;&#x4E00;&#x5207;&#x6B63;&#x5E38;&#xFF0C;&#x4F60;&#x4F1A;&#x6536;&#x5230;&#x5F39;&#x7A97;&#x63D0;&#x793A;<code>Room created and room code copied to clipboard</code>
      &#xFF08;&#x623F;&#x95F4;&#x5DF2;&#x5EFA;&#x7ACB;&#xFF0C;&#x8FDE;&#x63A5;&#x7801;&#x5DF2;&#x590D;&#x5236;&#x5230;&#x526A;&#x8D34;&#x677F;&#xFF09;&#xFF0C;&#x540C;&#x65F6;<code>&#x8FDE;&#x63A5;&#x7801;</code>&#x5C06;&#x81EA;&#x52A8;&#x62F7;&#x8D1D;&#x5230;&#x526A;&#x5207;&#x677F;&#x4E2D;&#xFF0C;&#x8BF7;&#x5C06;&#x5B83;&#x53D1;&#x7ED9;&#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x3002;
    </p>
    <h3 class="mume-header" id="%E5%BC%80%E5%A7%8B%E8%BF%9E%E6%8E%A5">&#x5F00;&#x59CB;&#x8FDE;&#x63A5;</h3>

    <p>
      &#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x6536;&#x5230;<code>room code&#xFF08;&#x8FDE;&#x63A5;&#x7801;&#xFF09;</code>&#x540E;&#xFF0C;&#x70B9;&#x51FB;<code>Sync Sofa</code>&#x63D2;&#x4EF6;&#x56FE;&#x6807;&#xFF0C;&#x7C98;&#x8D34;&#x5230;&#x8F93;&#x5165;&#x680F;&#x4E2D;&#x70B9;&#x51FB;<code>START&#xFF08;&#x5F00;&#x59CB;&#xFF09;</code>&#x6309;&#x94AE;&#x3002;
    </p>
    <p><img src="https://onns.xyz/blog/image/20200627-4.png" alt="User B"></p>
    <h3 class="mume-header" id="%E6%84%89%E5%BF%AB%E8%A7%82%E7%9C%8B%E5%90%A7">&#x6109;&#x5FEB;&#x89C2;&#x770B;&#x5427;
    </h3>

    <p><img src="https://onns.xyz/blog/image/20200627-5.png" alt="User A"><br>
      <img src="https://onns.xyz/blog/image/20200627-6.png" alt="User B"></p>
    <p>
      &#x73B0;&#x5728;&#x4F60;&#x53EF;&#x4EE5;&#x64AD;&#x653E;&#x89C6;&#x9891;&#x4E86;&#xFF0C;&#x4F60;&#x7684;&#x64AD;&#x653E;&#xFF0C;&#x6682;&#x505C;&#xFF0C;&#x66F4;&#x6539;&#x65F6;&#x95F4;&#x7B49;&#x64CD;&#x4F5C;&#x90FD;&#x4F1A;&#x540C;&#x6B65;&#x7ED9;&#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x3002;&#x6109;&#x5FEB;&#x5730;&#x540C;&#x6B65;&#x89C2;&#x770B;&#x5427;!
    </p>
    <h2 class="mume-header" id="vlc%E6%94%AF%E6%8C%81">VLC&#x652F;&#x6301;</h2>

    <p>
      &#x5982;&#x679C;&#x4F60;&#x4EEC;&#x90FD;&#x901A;&#x8FC7;<code>VLC &#x5A92;&#x4F53;&#x64AD;&#x653E;&#x5668;</code>&#x64AD;&#x653E;&#x89C6;&#x9891;&#xFF0C;<code>Sync Sofa</code>&#x4E5F;&#x53EF;&#x4EE5;&#x540C;&#x6B65;&#x4F60;&#x4EEC;&#x7684;&#x64CD;&#x4F5C;&#x3002;
    </p>
    <h3 class="mume-header"
      id="%E9%80%9A%E8%BF%87web%E6%8E%A7%E5%88%B6%E7%95%8C%E9%9D%A2%E6%93%8D%E6%8E%A7vlc%E6%92%AD%E6%94%BE">
      &#x901A;&#x8FC7;Web&#x63A7;&#x5236;&#x754C;&#x9762;&#x64CD;&#x63A7;VLC&#x64AD;&#x653E;</h3>

    <p>
      &#x9996;&#x5148;&#x4F60;&#x4EEC;&#x9700;&#x8981;&#x5F00;&#x542F;VLC&#x7684;Web&#x63A7;&#x5236;&#x754C;&#x9762;&#xFF0C;&#x4F7F;&#x6D4F;&#x89C8;&#x5668;&#x53EF;&#x4EE5;&#x63A7;&#x5236;VLC&#x7684;&#x64AD;&#x653E;&#xFF0C;&#x8BF7;&#x53C2;&#x8003;&#x4EE5;&#x4E0B;&#x5B98;&#x65B9;&#x6587;&#x6863;&#xFF1A;
    </p>
    <ul>
      <li><a
          href="https://wiki.videolan.org/Control_VLC_via_a_browser/">&#x901A;&#x8FC7;&#x6D4F;&#x89C8;&#x5668;&#x63A7;&#x5236;VLC</a>
      </li>
      <li><a
          href="https://wiki.videolan.org/Documentation:Modules/http_intf/#VLC_2.0.0_and_later">&#x5F00;&#x542F;VLC&#x7684;web&#x63A7;&#x5236;&#x754C;&#x9762;</a>
      </li>
    </ul>
    <ol>
      <li>&#x6253;&#x5F00;VLC&#x5A92;&#x4F53;&#x64AD;&#x653E;&#x5668;</li>
      <li>&#x8FDB;&#x5165;
        <code>&#x5DE5;&#x5177; &#x2192; &#x504F;&#x597D;&#x8BBE;&#x7F6E; (&#x5DE6;&#x4E0B;&#x89D2;&#x663E;&#x793A;&#x8BBE;&#x7F6E;&#x9009;&#x62E9; &quot;&#x5168;&#x90E8;&quot;) &#x2192; &#x754C;&#x9762; &#x2192; &#x4E3B;&#x754C;&#x9762;</code>,
        &#x52FE;&#x9009; &quot;Web&quot;<br>
        <img src="https://onns.xyz/blog/image/20200628-1.png" alt="Step 2"></li>
      <li>&#x8FDB;&#x5165;
        <code>&#x5DE5;&#x5177; &#x2192; &#x504F;&#x597D;&#x8BBE;&#x7F6E; (&#x5DE6;&#x4E0B;&#x89D2;&#x663E;&#x793A;&#x8BBE;&#x7F6E;&#x9009;&#x62E9; &quot;&#x5168;&#x90E8;&quot;) &#x2192; &#x754C;&#x9762; &#x2192; &#x4E3B;&#x754C;&#x9762; &#x2192; Lua</code>,
        &#x8BBE;&#x7F6E; <code>Lua HTTP - &#x5BC6;&#x7801;</code><br>
        <img src="https://onns.xyz/blog/image/20200628-2.png" alt="Step 3"></li>
      <li>&#x70B9;&#x51FB;<code>&#x4FDD;&#x5B58;</code>
        &#x5E76;&#x91CD;&#x542F;VLC&#x5A92;&#x4F53;&#x64AD;&#x653E;&#x5668;</li>
      <li>&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x6253;&#x5F00; <a
          href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a></li>
    </ol>
    <p>&#x8FD9;&#x65F6;&#x4F60;&#x7684;&#x7F51;&#x9875;&#x5E94;&#x8BE5;&#x5982;&#x4E0B;&#x56FE;&#x6240;&#x793A;:</p>
    <p><img src="https://onns.xyz/blog/image/20200628-3.png" alt="VLC media player - Web Interface"></p>
    <h3 class="mume-header" id="%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E7%A0%81-1">
      &#x83B7;&#x53D6;&#x8FDE;&#x63A5;&#x7801;</h3>

    <p>&#x786E;&#x8BA4;&#x5DF2;&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x6253;&#x5F00; <a
        href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>,<br>
      &#x70B9;&#x51FB; <code>Sync Sofa</code>
      &#x63D2;&#x4EF6;&#x56FE;&#x6807;&#x5E76;&#x70B9;&#x51FB;<code>REQUEST NEW CODE</code>&#xFF08;&#x83B7;&#x53D6;&#x94FE;&#x63A5;&#x7801;&#xFF09;
      &#x6309;&#x94AE;.</p>
    <p>
      &#x5982;&#x4E00;&#x5207;&#x6B63;&#x5E38;&#xFF0C;&#x4F60;&#x4F1A;&#x6536;&#x5230;&#x5F39;&#x7A97;&#x63D0;&#x793A;<code>Room created and room code copied to clipboard</code>&#xFF08;&#x623F;&#x95F4;&#x5DF2;&#x5EFA;&#x7ACB;&#xFF0C;&#x8FDE;&#x63A5;&#x7801;&#x5DF2;&#x590D;&#x5236;&#x5230;&#x526A;&#x8D34;&#x677F;&#xFF0C;&#x540C;&#x65F6;<code>&#x8FDE;&#x63A5;&#x7801;</code>&#x5C06;&#x81EA;&#x52A8;&#x62F7;&#x8D1D;&#x5230;&#x526A;&#x5207;&#x677F;&#x4E2D;&#xFF0C;&#x8BF7;&#x5C06;&#x5B83;&#x53D1;&#x7ED9;&#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x3002;
    </p>
    <h3 class="mume-header" id="%E5%BC%80%E5%A7%8B%E8%BF%9E%E6%8E%A5-1">&#x5F00;&#x59CB;&#x8FDE;&#x63A5;</h3>

    <p>
      &#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x6536;&#x5230;<code>room code</code>&#x540E;&#xFF0C;&#x70B9;&#x51FB;<code>Sync Sofa</code>&#x63D2;&#x4EF6;&#x56FE;&#x6807;&#xFF0C;&#x7C98;&#x8D34;&#x5230;&#x8F93;&#x5165;&#x680F;&#x4E2D;&#x70B9;&#x51FB;<code>START</code>&#xFF08;&#x5F00;&#x59CB;&#xFF09;&#x6309;&#x94AE;&#x3002;
    </p>
    <h3 class="mume-header" id="%E6%84%89%E5%BF%AB%E8%A7%82%E7%9C%8B%E5%90%A7-1">
      &#x6109;&#x5FEB;&#x89C2;&#x770B;&#x5427;</h3>

    <p>
      &#x73B0;&#x5728;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>Sync Sofa</code>&#x901A;&#x8FC7;VLC&#x540C;&#x6B65;&#x672C;&#x5730;&#x89C6;&#x9891;&#x64AD;&#x653E;&#x72B6;&#x6001;&#x4E86;&#xFF0C;&#x4F60;&#x7684;&#x64AD;&#x653E;&#xFF0C;&#x6682;&#x505C;&#xFF0C;&#x66F4;&#x6539;&#x65F6;&#x95F4;&#x7B49;&#x64CD;&#x4F5C;&#x90FD;&#x4F1A;&#x540C;&#x6B65;&#x7ED9;&#x4F60;&#x7684;&#x5C0F;&#x4F19;&#x4F34;&#x3002;&#x6109;&#x5FEB;&#x5730;&#x540C;&#x6B65;&#x89C2;&#x770B;&#x5427;!
    </p>
    <p><strong>&#x6CE8;&#x610F;</strong>:</p>
    <p>&#x26A0;&#xFE0F; &#x5728;&#x64AD;&#x653E;&#x65F6;&#xFF0C;&#x5207;&#x52FF;&#x5173;&#x95ED;<a
        href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>&#x9875;&#x9762;&#x3002;</p>
    <h3 class="mume-header" id="%E5%85%B3%E9%97%AD%E6%8E%A7%E5%88%B6%E9%A1%B5%E9%9D%A2">
      &#x5173;&#x95ED;&#x63A7;&#x5236;&#x9875;&#x9762;</h3>

    <p>
      &#x89C6;&#x9891;&#x64AD;&#x653E;&#x5B8C;&#x6BD5;&#x540E;&#xFF0C;&#x70B9;&#x51FB;<code>Sync Sofa</code>&#x63D2;&#x4EF6;&#x9875;&#x9762;&#x4E0A;&#x7684;<code>STOP</code>&#x6309;&#x94AE;&#xFF0C;&#x6216;&#x5173;&#x95ED;<a
        href="http://127.0.0.1:8080/">http://127.0.0.1:8080/</a>&#x9875;&#x9762;&#x3002;</p>
    <h2 class="mume-header" id="%E5%AE%89%E8%A3%85">&#x5B89;&#x88C5;</h2>

    <h3 class="mume-header" id="%E8%B0%B7%E6%AD%8C%E6%B5%8F%E8%A7%88%E5%99%A8">&#x8C37;&#x6B4C;&#x6D4F;&#x89C8;&#x5668;
    </h3>

    <h4 class="mume-header" id="%E4%BB%8E%E8%B0%B7%E6%AD%8C%E5%95%86%E5%BA%97%E5%AE%89%E8%A3%85">
      &#x4ECE;&#x8C37;&#x6B4C;&#x5546;&#x5E97;&#x5B89;&#x88C5;</h4>

    <ol>
      <li>&#x5728;Chrome&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x6253;&#x5F00; <a
          href="https://chrome.google.com/webstore/detail/sync-sofa-online-video-sy/kgpnhgmpijhpkefpddoehhminpfiddmg">Sync
          Sofa - Online Video Synchronizer - Chrome Web Store</a></li>
      <li>&#x70B9;&#x51FB; <code>Add to Chrome</code> &#x6309;&#x94AE;</li>
      <li>&#x9009;&#x62E9; <code>Add extension</code></li>
    </ol>
    <h4 class="mume-header" id="%E4%BB%8E%E6%9C%AC%E5%9C%B0-crx-%E6%96%87%E4%BB%B6%E5%AE%89%E8%A3%85">
      &#x4ECE;&#x672C;&#x5730; .crx &#x6587;&#x4EF6;&#x5B89;&#x88C5;</h4>

    <ol>
      <li>&#x6253;&#x5F00; <a href="https://github.com/LouisYLWang/Sync-Sofa/releases/latest">Github release
          page&#xFF08;&#x7248;&#x672C;&#x53D1;&#x5E03;&#x9875;&#x9762;&#xFF09;</a></li>
      <li>&#x4E0B;&#x8F7D; <code>sync_sofa.[version].crx</code>, <em>[version]</em>
        &#x4E3A;&#x5F53;&#x524D;&#x6700;&#x65B0;&#x7248;&#x672C;&#x7F16;&#x53F7;</li>
      <li>&#x5728;Chrome&#x6D4F;&#x89C8;&#x5668;&#x5730;&#x5740;&#x680F;&#x4E2D;&#x8F93;&#x5165;
        <code>chrome://extensions/</code></li>
      <li>&#x542F;&#x7528; <code>&#x5F00;&#x53D1;&#x8005;&#x6A21;&#x5F0F;</code>
        (&#x9875;&#x9762;&#x53F3;&#x4E0A;&#x89D2;)</li>
      <li>&#x5C06; <code>sync_sofa.[&#x7248;&#x672C;&#x53F7;].crx</code> &#x62D6;&#x5165;
        <code>chrome://extensions/</code> &#x9875;&#x9762;</li>
      <li>&#x70B9;&#x51FB; <code>&#x6DFB;&#x52A0;&#x63D2;&#x4EF6;</code> &#x6309;&#x94AE;</li>
    </ol>
    <p><strong>&#x6CE8;&#x610F;</strong>:<br>
      &#x5982;&#x679C;&#x8BE5;&#x63D2;&#x4EF6;&#x88AB;Chrome&#x6D4F;&#x89C8;&#x5668;&#x7981;&#x7528;&#xFF0C;&#x8BF7;&#x5C1D;&#x8BD5;
      <a
        href="#%E4%BB%8E%E8%B0%B7%E6%AD%8C%E5%95%86%E5%BA%97%E5%AE%89%E8%A3%85">&#x4ECE;&#x8C37;&#x6B4C;&#x5546;&#x5E97;&#x5B89;&#x88C5;</a>
      &#x6216;&#x8005; <a
        href="#%E5%AE%89%E8%A3%85%E6%9C%AA%E6%89%93%E5%8C%85%E7%9A%84%E6%8F%92%E4%BB%B6">&#x5B89;&#x88C5;&#x672A;&#x6253;&#x5305;&#x7684;&#x63D2;&#x4EF6;</a>
    </p>
    <blockquote>
      <p>This extension is not listed in the Chrome Web Store and may have been added without your knowledge.</p>
    </blockquote>
    <h4 class="mume-header" id="%E5%AE%89%E8%A3%85%E6%9C%AA%E6%89%93%E5%8C%85%E7%9A%84%E6%8F%92%E4%BB%B6">
      &#x5B89;&#x88C5;&#x672A;&#x6253;&#x5305;&#x7684;&#x63D2;&#x4EF6;</h4>

    <ol>
      <li>&#x4E0B;&#x8F7D; <a
          href="https://github.com/LouisYLWang/Sync-Sofa/archive/master.zip">&#x7A33;&#x5B9A;&#x7248;&#x672C;</a> or <a
          href="https://github.com/LouisYLWang/Sync-Sofa/archive/dev.zip">&#x5F00;&#x53D1;&#x7248;&#x672C;</a>
        (&#x65B0;&#x7279;&#x6027;&#xFF0C;&#x4E5F;&#x8BB8;&#x4E5F;&#x6709;bug)</li>
      <li>&#x89E3;&#x538B;&#x4F60;&#x4E0B;&#x8F7D;&#x7684;<code>.zip</code> &#x538B;&#x7F29;&#x6587;&#x4EF6;</li>
      <li>&#x5728;Chrome&#x5730;&#x5740;&#x680F;&#x8F93;&#x5165; <code>chrome://extensions/</code>
        &#x6253;&#x5F00;&#x63D2;&#x4EF6;&#x7BA1;&#x7406;&#x9875;&#x9762;</li>
      <li>&#x5F00;&#x542F;&#x53F3;&#x4E0A;&#x89D2;<code>&#x5F00;&#x53D1;&#x8005;&#x6A21;&#x5F0F;</code> &#x6309;&#x94AE;
      </li>
      <li>
        &#x70B9;&#x51FB;&#x5DE6;&#x4E0A;&#x89D2;<code>&#x52A0;&#x8F7D;&#x672A;&#x6253;&#x5305;&#x7684;&#x62D3;&#x5C55;</code>
        &#x6309;&#x94AE;</li>
      <li>&#x9009;&#x62E9;
        <code>&#x4E0B;&#x8F7D;&#x8DEF;&#x5F84;/&#x89E3;&#x538B;&#x8DEF;&#x5F84;/client/chrome_extension</code></li>
      <li>&#x70B9;&#x51FB; <code>&#x9009;&#x62E9;</code></li>
    </ol>
    <h3 class="mume-header" id="%E5%BE%AE%E8%BD%AFedge%E6%B5%8F%E8%A7%88%E5%99%A8">
      &#x5FAE;&#x8F6F;Edge&#x6D4F;&#x89C8;&#x5668;:</h3>

    <h4 class="mume-header"
      id="%E4%BB%8Eedge%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8F%92%E4%BB%B6%E4%B8%AD%E5%BF%83%E5%AE%89%E8%A3%85">
      &#x4ECE;Edge&#x6D4F;&#x89C8;&#x5668;&#x63D2;&#x4EF6;&#x4E2D;&#x5FC3;&#x5B89;&#x88C5;</h4>

    <ol>
      <li>&#x5728;Edge&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x6253;&#x5F00; <a
          href="https://microsoftedge.microsoft.com/addons/detail/kpfbclpafmmjalikjjlcoddffpfgghgp">Sync Sofa - Online
          Video Synchronizer - Microsoft Edge Addons</a></li>
      <li>&#x70B9;&#x51FB; <code>&#x83B7;&#x53D6;</code> &#x6309;&#x94AE;</li>
    </ol>
    <h3 class="mume-header" id="firefox%E5%90%8E%E7%BB%AD%E7%89%88%E6%9C%AC%E6%B7%BB%E5%8A%A0%E6%94%AF%E6%8C%81">
      Firefox&#xFF08;&#x540E;&#x7EED;&#x7248;&#x672C;&#x6DFB;&#x52A0;&#x652F;&#x6301;&#xFF09;</h3>

    <p><s>&#x5176;&#x5B9E;&#x4E5F;&#x53EF;&#x80FD;&#x4E0D;&#x4F1A;</s></p>
    <h2 class="mume-header" id="%E6%9C%8D%E5%8A%A1%E7%AB%AF%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97">
      &#x670D;&#x52A1;&#x7AEF;&#x90E8;&#x7F72;&#x6307;&#x5357;</h2>

    <p><strong>&#x6CE8;&#x610F;</strong>:</p>
    <p>&#x26A0;&#xFE0F;
      &#x90E8;&#x7F72;&#x524D;&#xFF0C;&#x5EFA;&#x8BAE;&#x4F60;&#x7684;&#x670D;&#x52A1;&#x5668;&#x5DF2;&#x7ECF;&#x90E8;&#x7F72;&#x4E86;SSL/TLS&#x8BC1;&#x4E66;&#xFF0C;&#x5E76;&#x5DF2;&#x8FDE;&#x63A5;&#x5230;&#x57DF;&#x540D;&#x3002;&#x4EE5;&#x4E0B;&#x90E8;&#x7F72;&#x811A;&#x672C;&#x57FA;&#x4E8E;&#x4F7F;&#x7528;Let&apos;s
      Encrypt
      certificates&#x9A8C;&#x8BC1;&#x7684;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5982;&#x4F7F;&#x7528;&#x5176;&#x4ED6;&#x7684;&#x8BC1;&#x4E66;&#x63D0;&#x4F9B;&#x5546;&#xFF0C;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x4FEE;&#x6539;&#x90E8;&#x5206;&#x811A;&#x672C;&#x4EE5;&#x6B63;&#x5E38;&#x8FD0;&#x884C;&#x3002;
    </p>
    <p>&#x26A0;&#xFE0F;
      dev&#x6A21;&#x5F0F;&#x4F7F;&#x7528;http&#x534F;&#x8BAE;&#x8FDB;&#x884C;&#x4F20;&#x8F93;&#xFF0C;prod&#x4F7F;&#x7528;https&#x534F;&#x8BAE;&#x8FDB;&#x884C;&#x4F20;&#x8F93;
    </p>
    <h3 class="mume-header"
      id="%E7%9B%B4%E6%8E%A5%E9%83%A8%E7%BD%B2%E4%B8%8D%E4%BD%BF%E7%94%A8docker%E5%AE%B9%E5%99%A8">
      &#x76F4;&#x63A5;&#x90E8;&#x7F72;&#xFF08;&#x4E0D;&#x4F7F;&#x7528;Docker&#x5BB9;&#x5668;&#xFF09;:</h3>

    <p><strong>1. &#x83B7;&#x53D6;&#x6267;&#x884C;&#x6587;&#x4EF6;</strong></p>
    <ul>
      <li>
        <p>
          &#x5982;&#x679C;&#x4F60;&#x60F3;&#x8981;&#x4FEE;&#x6539;&#x6E90;&#x4EE3;&#x7801;&#x5E76;&#x81EA;&#x884C;&#x7F16;&#x8BD1;&#xFF0C;&#x8BF7;&#x6267;&#x884C;&#x4EE5;&#x4E0B;shell&#x811A;&#x672C;&#x83B7;&#x53D6;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x3002;&#x5728;&#x6267;&#x884C;&#x524D;&#xFF0C;&#x8BF7;&#x786E;&#x8BA4;&#x670D;&#x52A1;&#x5668;&#x5DF2;&#x5B89;&#x88C5;<code>Go</code>&#x7684;&#x73AF;&#x5883;
        </p>
        <pre data-role="codeBlock" data-info="shell" class="language-shell">go get github.com/LouisYLWang/Sync-Sofa/server
<span class="token comment"># &#x5982;&#x679C;&#x4F60;&#x4E0D;&#x6E05;&#x695A; $GOPATH</span>
<span class="token comment"># &#x8BF7;&#x5C1D;&#x8BD5;&#x8F93;&#x5165;&#x5E76;&#x6267;&#x884C; &quot;go env GOPATH&quot;</span>
<span class="token function">cd</span> <span class="token variable">$GOPATH</span>/src/github.com/LouisYLWang/Sync-Sofa/server

<span class="token comment"># &#xFF08;&#x4E0B;&#x4E00;&#x6B65;&#x53EF;&#x7701;&#x7565;&#xFF09;</span>
<span class="token comment"># &#x5982;&#x679C;&#x4F60;&#x770B;&#x5230;&#x4E86;&#x8FD9;&#x6761;&#x6D88;&#x606F;:</span>
<span class="token comment"># &quot;dial tcp 216.58.200.49:443: i/o timeout&quot;</span>
<span class="token comment"># &#x8BF7;&#x6DFB;&#x52A0;&#x5E76;&#x6267;&#x884C;&#x4E0B;&#x4E00;&#x6761;&#x547D;&#x4EE4;</span>
<span class="token function">export</span> GOPROXY<span class="token operator">=</span>https://goproxy.io

go <span class="token function">install</span>
<span class="token function">cd</span> <span class="token variable">$GOPATH</span>/bin
</pre>
      </li>
      <li>
        <p>
          &#x5982;&#x679C;&#x65E0;&#x9700;&#x4FEE;&#x6539;&#x6E90;&#x4EE3;&#x7801;&#x5E76;&#x81EA;&#x884C;&#x7F16;&#x8BD1;&#xFF0C;&#x4F60;&#x4E5F;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x4E0B;&#x8F7D;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;:
        </p>
        <ol>
          <li>&#x6253;&#x5F00; <a href="https://github.com/LouisYLWang/Sync-Sofa/releases/latest">Github release
              page</a></li>
          <li>&#x4E0B;&#x8F7D; <code>server</code>
            &#x6587;&#x4EF6;&#xFF08;&#x9002;&#x7528;&#x4E8E;linux&#x670D;&#x52A1;&#x5668;&#xFF09;</li>
          <li>&#x4E0B;&#x8F7D; <code>config.json</code>
            &#x6587;&#x4EF6;&#xFF0C;&#x79FB;&#x52A8;&#x81F3;<code>server</code>&#x540C;&#x4E00;&#x8DEF;&#x5F84;</li>
        </ol>
      </li>
    </ul>
    <p><strong>2. &#x4FEE;&#x6539;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF1A;</strong></p>
    <ul>
      <li>
        <p>&#x914D;&#x7F6E;&#x53D8;&#x91CF;&#xFF1A;</p>
        <ul>
          <li><code>addr</code>: &#x670D;&#x52A1;&#x5668;&#x7AEF;&#x53E3;</li>
          <li><code>runmode</code>:
            <ul>
              <li>dev:
                &#x5F00;&#x53D1;&#x6A21;&#x5F0F;&#xFF08;&#x5EFA;&#x8BAE;&#x672C;&#x5730;&#x4F7F;&#x7528;&#xFF0C;&#x4E0D;&#x5305;&#x542B;&#x5BF9;HTTPS&#x7684;&#x652F;&#x6301;&#xFF09;
              </li>
              <li>prod: &#x751F;&#x4EA7;&#x6A21;&#x5F0F;</li>
            </ul>
          </li>
          <li><code>tlsdir</code>:
            <ul>
              <li><code>tlskey</code>: TLS&#x8BC1;&#x4E66;&#x79C1;&#x94A5;&#x8DEF;&#x5F84;</li>
              <li><code>tlscert</code>: TLS&#x8BC1;&#x4E66;&#x8DEF;&#x5F84;</li>
            </ul>
          </li>
        </ul>
        <p><strong>Notices</strong>: <code>addr</code>, <code>runmode</code> &#x4E3A;&#x5FC5;&#x987B;&#x53C2;&#x6570;,
          <code>tlskey</code>, <code>tlscert</code>
          &#x53C2;&#x6570;&#x5728;&#x4F7F;&#x7528;HTTPS&#x8FDE;&#x63A5;&#x65F6;&#xFF08;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E0B;&#xFF09;&#x4E3A;&#x5FC5;&#x987B;&#x53C2;&#x6570;
        </p>
      </li>
      <li>
        <p>&#x5F00;&#x53D1;&#x6A21;&#x5F0F;&#xFF08;http&#xFF09;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x6837;&#x4F8B;:</p>
        <pre data-role="codeBlock" data-info="json" class="language-json"><span class="token punctuation">{</span>
  <span class="token property">&quot;addr&quot;</span><span class="token operator">:</span> <span class="token string">&quot;:80&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;runmode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;dev&quot;</span>
<span class="token punctuation">}</span>
</pre>
      </li>
      <li>
        <p>&#x751F;&#x4EA7;&#x6A21;&#x5F0F;&#xFF08;https&#xFF09;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x6837;&#x4F8B;:</p>
        <pre data-role="codeBlock" data-info="json" class="language-json"><span class="token punctuation">{</span>
  <span class="token property">&quot;addr&quot;</span><span class="token operator">:</span> <span class="token string">&quot;:443&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;runmode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;prod&quot;</span><span class="token punctuation">,</span>
  <span class="token property">&quot;tlsdir&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token property">&quot;tlskey&quot;</span><span class="token operator">:</span> <span class="token string">&quot;/etc/letsencrypt/live/your.host.url/privkey.pem&quot;</span><span class="token punctuation">,</span>
    <span class="token property">&quot;tlscert&quot;</span><span class="token operator">:</span> <span class="token string">&quot;/etc/letsencrypt/live/your.host.url/fullchain.pem&quot;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

</pre>
      </li>
    </ul>
    <p><strong>3.
        &#x5728;&#x6267;&#x884C;&#x6587;&#x4EF6;&#x6240;&#x5728;&#x8DEF;&#x5F84;&#x4E0B;&#xFF0C;&#x6267;&#x884C;
        <code>./server</code> &#x90E8;&#x7F72;&#x670D;&#x52A1;&#x5668;,
        &#x90E8;&#x7F72;&#x6210;&#x529F;&#x4FE1;&#x606F;&#x5982;&#x4E0B;:</strong></p>
    <pre data-role="codeBlock" data-info class="language-"><code>found config file, read parameters from config file...
server is listening at {your_port_number}...
</code></pre>
    <h3 class="mume-header" id="%E4%BD%BF%E7%94%A8docker%E5%AE%B9%E5%99%A8%E9%83%A8%E7%BD%B2">
      &#x4F7F;&#x7528;Docker&#x5BB9;&#x5668;&#x90E8;&#x7F72;</h3>

    <p>
      &#x5728;&#x90E8;&#x7F72;&#x524D;&#x8BF7;&#x786E;&#x8BA4;Docker&#x5BB9;&#x5668;&#x5728;&#x670D;&#x52A1;&#x5668;&#x7AEF;&#x53EF;&#x6B63;&#x5E38;&#x8FD0;&#x884C;&#xFF0C;&#x8BF7;&#x6309;&#x7167;&#x5982;&#x4E0B;&#x63D0;&#x793A;&#x4FEE;&#x6539;&#x53C2;&#x6570;
    </p>
    <ul>
      <li>
        <p>&#x914D;&#x7F6E;&#x53D8;&#x91CF;&#xFF1A;</p>
        <ul>
          <li><code>ADDR</code>: &#x670D;&#x52A1;&#x5668;&#x7AEF;&#x53E3;</li>
          <li><code>RUNMODE</code>:
            <ul>
              <li>dev:
                &#x5F00;&#x53D1;&#x6A21;&#x5F0F;&#xFF08;&#x5EFA;&#x8BAE;&#x672C;&#x5730;&#x4F7F;&#x7528;&#xFF0C;&#x4E0D;&#x5305;&#x542B;&#x5BF9;HTTPS&#x7684;&#x652F;&#x6301;&#xFF09;
              </li>
              <li>prod: &#x751F;&#x4EA7;&#x6A21;&#x5F0F;</li>
            </ul>
          </li>
          <li><code>APIHOST</code>: &#x670D;&#x52A1;&#x5668;&#x7F51;&#x5740;</li>
          <li><code>IMGNAME</code>: docker&#x5BB9;&#x5668;&#x540D;&#x79F0;&#xFF08;&#x53EF;&#x81EA;&#x9009;&#xFF09;</li>
          <li><code>TLSKEYPATH</code>: TLS&#x8BC1;&#x4E66;&#x79C1;&#x94A5;&#x8DEF;&#x5F84;</li>
          <li><code>TLSCERTPATH</code>: TLS&#x8BC1;&#x4E66;&#x8DEF;&#x5F84;</li>
        </ul>
      </li>
      <li>
        <p>&#x5F00;&#x53D1;&#x6A21;&#x5F0F;&#xFF08;http&#xFF09;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x6837;&#x4F8B;:</p>
        <pre data-role="codeBlock" data-info="sh" class="language-bash">docker pull louisylwang/watchtogether

<span class="token function">export</span> ADDR<span class="token operator">=</span>:4000 \      
<span class="token function">export</span> RUNMODE<span class="token operator">=</span>dev \   
<span class="token function">export</span> IMGNAME<span class="token operator">=</span>yourimagename \   

docker run -d \
-e ADDR<span class="token operator">=</span>:4000 \
-e RUNMODE<span class="token operator">=</span>RUNMODE \
-p 4000:4000 \
--name IMGNAME louisylwang/watchtogether
</pre>
      </li>
      <li>
        <p>&#x751F;&#x4EA7;&#x6A21;&#x5F0F;&#xFF08;https&#xFF09;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x6837;&#x4F8B;:</p>
        <pre data-role="codeBlock" data-info="sh" class="language-bash">docker pull louisylwang/watchtogether

<span class="token function">export</span> ADDR<span class="token operator">=</span>:443 \      
<span class="token function">export</span> RUNMODE<span class="token operator">=</span>prod \   
<span class="token function">export</span> APIHOST<span class="token operator">=</span>your.host.name \   
<span class="token function">export</span> IMGNAME<span class="token operator">=</span>yourimagename \   
<span class="token function">export</span> TLSKEYPATH<span class="token operator">=</span>/your/path/to/TLS/privatekey \
<span class="token function">export</span> TLSCERTPATH<span class="token operator">=</span>/your/path/to/TLS/certification \


docker run -d \
-e ADDR<span class="token operator">=</span>:ADDR \
<span class="token comment">#docker port to server:server port to docker, not necessarily the same</span>
-p ADDR:ADDR \ 
-e RUNMODE<span class="token operator">=</span>RUNMODE \
<span class="token comment">#if you use letsencrypt, TLSKEY value should be /etc/letsencrypt/live/$APIHOST/privkey.pem</span>
-e TLSKEY<span class="token operator">=</span>TLSKEYPATH \ 
<span class="token comment">#if you use letsencrypt, TLSCERT value should be /etc/letsencrypt/live/$APIHOST/fullchain.pem </span>
-e TLSCERT<span class="token operator">=</span>TLSCERTPATH \ 
<span class="token comment">#need to expose your TLS certification file to docker</span>
-v /etc/letsencrypt:/etc/letsencrypt:ro \ 
--name IMGNAME louisylwang/watchtogether \
--restart<span class="token operator">=</span>always
</pre>
      </li>
      <li>
        <p>&#x90E8;&#x7F72;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x6267;&#x884C;
          <code>docker logs {your docker image name}</code>&#x5C06;&#x4F1A;&#x63D0;&#x793A;&#x4E0B;&#x5217;&#x65E5;&#x5FD7;&#x4FE1;&#x606F;:
        </p>
        <pre data-role="codeBlock" data-info class="language-"><code>not found config file, read parameters from system variables...
YYYY/MM/DD HH:MM:SS server is listening at :ADDR...
</code></pre>
      </li>
    </ul>
    <h2 class="mume-header" id="%E7%89%88%E6%9C%AC%E6%97%A5%E5%BF%97">&#x7248;&#x672C;&#x65E5;&#x5FD7;</h2>

    <h3 class="mume-header" id="v107-1">v1.0.7</h3>

    <h2>&#x1F6E0; 2020&#x5E74;7&#x6708;5&#x65E5;&#x66F4;&#x65B0;</h2>
    <p>&#x26A0;&#x26A0;&#x26A0; &#x6CE8;&#x610F;&#xFF0C;&#x6B64;&#x7248;&#x672C;&#x4E0E;&lt;=
      1.0.5&#x7684;&#x4EFB;&#x4F55;&#x7248;&#x672C;&#x90FD;&#x4E0D;&#x517C;&#x5BB9;&#xFF0C;&#x8BF7;&#x52A1;&#x5FC5;&#x786E;&#x4FDD;&#x4F60;&#x7684;&#x7248;&#x672C;&#x4E0E;&#x5C0F;&#x4F19;&#x4F34;&#x7684;&#x7248;&#x672C;&#x4E00;&#x81F4;&#x3002;
    </p>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>
            &#x65B0;&#x589E;&#x7248;&#x672C;&#x68C0;&#x6D4B;&#xFF08;&#x9AD8;&#x7248;&#x672C;&#x7528;&#x6237;&#x4E0E;&#x4F4E;&#x7248;&#x672C;&#x7528;&#x6237;&#x8FDE;&#x63A5;&#x65F6;&#xFF0C;&#x82E5;&#x8FDE;&#x63A5;&#x7801;&#x7531;&#x4F4E;&#x7248;&#x672C;&#x7528;&#x6237;&#x7533;&#x8BF7;&#xFF0C;&#x9AD8;&#x7248;&#x672C;&#x7528;&#x6237;&#x5C06;&#x6536;&#x5230;&#x63D0;&#x793A;&#xFF0C;&#x8BF7;&#x6839;&#x636E;&#x63D0;&#x793A;&#x544A;&#x77E5;&#x5BF9;&#x65B9;&#x5347;&#x7EA7;&#x6700;&#x65B0;&#x7248;&#x672C;&#xFF09;
          </li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;:
        <ul>
          <li>&#x4FEE;&#x590D;&#x5BF9; <a href="https://www.bilibili.com/bangumi/*">bilibili movie</a>
            &#x7684;&#x652F;&#x6301;</li>
          <li>
            &#x4FEE;&#x590D;&#x4E86;&#x4F18;&#x9177;&#x53CA;&#x8292;&#x679C;TV&#x65E0;&#x6CD5;&#x540C;&#x6B65;&#x64CD;&#x4F5C;&#x7684;&#x95EE;&#x9898;
          </li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v106-1">v1.0.6</h3>

    <h2>&#x1F6E0; 2020&#x5E74;6&#x6708;28&#x65E5;&#x66F4;&#x65B0;</h2>
    <p>&#x26A0;&#x26A0;&#x26A0;
      &#x6CE8;&#x610F;&#xFF0C;&#x6B64;&#x7248;&#x672C;&#x4E0E;&#x4E4B;&#x524D;&#x7684;&#x4EFB;&#x4F55;&#x7248;&#x672C;&#x90FD;&#x4E0D;&#x517C;&#x5BB9;&#xFF0C;&#x8BF7;&#x52A1;&#x5FC5;&#x786E;&#x4FDD;&#x4F60;&#x7684;&#x7248;&#x672C;&#x4E0E;&#x5C0F;&#x4F19;&#x4F34;&#x7684;&#x7248;&#x672C;&#x4E00;&#x81F4;&#x3002;
    </p>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>
            &#x652F;&#x6301;&#x8292;&#x679C;TV&#xFF08;&#x6765;&#x4E58;&#x98CE;&#x7834;&#x6D6A;&#x5427;&#xFF01;&#x1F923;&#xFF09;
          </li>
          <li>
            &#x652F;&#x6301;&#x4F7F;&#x7528;VLC&#x64AD;&#x653E;&#x5668;&#x540C;&#x6B65;&#x64AD;&#x653E;&#x672C;&#x5730;&#x89C6;&#x9891;&#x6587;&#x4EF6;
          </li>
          <li>&#x65B0;&#x589E;&#x8BBE;&#x7F6E;&#x9875;&#x9762;-&#x8C03;&#x8BD5;&#x6A21;&#x5F0F;</li>
          <li>&#x65B0;&#x589E;&#x6350;&#x8D60;&#x9875;&#x9762;</li>
          <li>&#x65B0;&#x589E;wiki&#x9875;&#x9762;</li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;:
        <ul>
          <li>&#x63D0;&#x9AD8;&#x540C;&#x6B65;&#x7684;&#x7A33;&#x5B9A;&#x6027;:
            <ul>
              <li>
                &#x66F4;&#x65B0;&#x4E86;&#x540C;&#x6B65;&#x903B;&#x8F91;&#xFF08;&#x4E0D;&#x4E0E;&#x4E4B;&#x524D;&#x7684;&#x4EFB;&#x4F55;&#x7248;&#x672C;&#x517C;&#x5BB9;&#xFF0C;&#x8BF7;&#x5C3D;&#x5FEB;&#x66F4;&#x65B0;&#x81F3;1.0.6+&#xFF09;
              </li>
              <li>&#x589E;&#x52A0;&#x7F13;&#x51B2;&#x68C0;&#x6D4B;</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v105-1">v1.0.5</h3>

    <h2>&#x1F6E0; 2020&#x5E74;5&#x6708;12&#x65E5;&#x66F4;&#x65B0;</h2>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x589E;&#x52A0;&#x5BF9;Edge&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x652F;&#x6301;</li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x63D0;&#x9AD8;&#x540C;&#x6B65;&#x7684;&#x7A33;&#x5B9A;&#x6027;</li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v104-1">v1.0.4</h3>

    <h2>&#x1F6E0; 2020&#x5E74;5&#x6708;10&#x65E5;&#x66F4;&#x65B0;</h2>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x65B0;&#x589E;&#x6210;&#x529F;&#x8FDE;&#x63A5;&#x63D0;&#x793A;</li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x63D0;&#x9AD8;&#x540C;&#x6B65;&#x7684;&#x7A33;&#x5B9A;&#x6027;</li>
          <li>&#x4FEE;&#x6539;&#x6D88;&#x606F;&#x5F39;&#x7A97;&#x6837;&#x5F0F;</li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v103-1">v1.0.3</h3>

    <h2>&#x1F6E0; 2020&#x5E74;5&#x6708;8&#x65E5;&#x66F4;&#x65B0;</h2>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x65B0;&#x589E;&#x5BF9;&#x4EE5;&#x4E0B;&#x89C6;&#x9891;&#x7F51;&#x7AD9;&#x7684;&#x652F;&#x6301;
            <ul>
              <li><a href="https://www.iqiyi.com/">&#x7231;&#x5947;&#x827A;</a></li>
              <li><a href="https://www.youku.com/">&#x4F18;&#x9177;</a></li>
              <li><a href="https://www.weiyun.com/">&#x5FAE;&#x4E91;</a></li>
              <li><a href="https://v.qq.com/">&#x817E;&#x8BAF;&#x89C6;&#x9891;</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x63D0;&#x9AD8;&#x540C;&#x6B65;&#x7684;&#x7A33;&#x5B9A;&#x6027;</li>
          <li>&#x4FEE;&#x6539;&#x6587;&#x6863;</li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v102-1">v1.0.2</h3>

    <h2>&#x1F6E0; 2020&#x5E74;3&#x6708;31&#x65E5;&#x66F4;&#x65B0;</h2>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x652F;&#x6301;&#x5BF9;&#x4FEE;&#x6539;&#x64AD;&#x653E;&#x8FDB;&#x5EA6;&#x7684;&#x540C;&#x6B65;</li>
        </ul>
      </li>
      <li>&#x4FEE;&#x590D;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x63D0;&#x9AD8;&#x540C;&#x6B65;&#x7684;&#x7A33;&#x5B9A;&#x6027;</li>
        </ul>
      </li>
    </ul>
    <h3 class="mume-header" id="v001-1">v0.0.1</h3>

    <h2>&#x1F6E0; 2020&#x5E74;3&#x6708;26&#x65E5;&#x66F4;&#x65B0; (&#x6D4B;&#x8BD5;&#x7248;)</h2>
    <ul>
      <li>&#x65B0;&#x589E;&#x529F;&#x80FD;&#xFF1A;
        <ul>
          <li>&#x652F;&#x6301;&#x64AD;&#x653E;&#x6682;&#x505C;&#x540C;&#x6B65;</li>
          <li>&#x652F;&#x6301;&#x65AD;&#x5F00;&#x8FDE;&#x63A5;&#x63D0;&#x793A;</li>
        </ul>
      </li>
    </ul>
    <h2 class="mume-header" id="%E5%BC%80%E5%8F%91%E8%80%85">&#x5F00;&#x53D1;&#x8005;</h2>

    <p>Yiliang &quot;Louis&quot; Wang &#x2013; <a href="https://ylwang.codes/">@blog</a> &#x2013; <a
        href="mailto:louis.yl.wang@outlook.com">@mail</a></p>
    <p>Onns &#x2013; <a href="https://onns.xyz/">@blog</a> &#x2013; <a href="mailto:onns@onns.xyz">@mail</a></p>
    <h2 class="mume-header" id="%E5%8F%82%E4%B8%8E%E6%9B%B4%E6%96%B0">&#x53C2;&#x4E0E;&#x66F4;&#x65B0;</h2>

    <ol>
      <li>&#x62F7;&#x8D1D;&#x5F53;&#x524D;&#x4EE3;&#x7801;&#xFF08;<a
          href="https://github.com/LouisYLWang/Sync-Sofa/fork%EF%BC%89">https://github.com/LouisYLWang/Sync-Sofa/fork&#xFF09;</a>
      </li>
      <li>&#x521B;&#x5EFA;&#x4F60;&#x81EA;&#x5DF1;&#x7684;&#x5206;&#x652F; (<code>git checkout -b feature/fooBar</code>)
      </li>
      <li>&#x6DFB;&#x52A0;&#x8BC4;&#x8BBA; (<code>git commit -am &apos;Add some fooBar&apos;</code>)</li>
      <li>&#x63D0;&#x4EA4;&#x4EE3;&#x7801; (<code>git push origin feature/fooBar</code>)</li>
      <li>&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x66F4;&#x65B0;&#x8BF7;&#x6C42;</li>
    </ol>
    <h2 class="mume-header" id="%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">&#x5E38;&#x89C1;&#x95EE;&#x9898;</h2>

    <ol>
      <li>
        <p><strong>Q:</strong>
          &#x5728;&#x6211;&#x5B89;&#x88C5;&#x7684;&#x65F6;&#x5019;&#xFF0C;Chrome&#x63D0;&#x793A;&#x6211;Sync
          Sofa&#x53EF;&#x4EE5;<code>&#x8BFB;&#x53D6;&#x548C;&#x66F4;&#x6539;&#x60A8;&#x5728;&#x4E00;&#x4E9B;&#x7F51;&#x7AD9;&#x4E0A;&#x7684;&#x6570;&#x636E;</code>&#x4EE5;&#x53CA;<code>&#x8BFB;&#x53D6;&#x60A8;&#x7684;&#x6D4F;&#x89C8;&#x8BB0;&#x5F55;</code>&#xFF0C;&#x542C;&#x8D77;&#x6765;&#x5F88;&#x4E25;&#x91CD;&#xFF0C;&#x5B83;&#x5B89;&#x5168;&#x5417;&#xFF1F;
        </p>
        <p><strong>A:</strong>
          &#x6211;&#x4EEC;&#x4E0D;&#x4F1A;&#x6536;&#x96C6;&#x4F60;&#x7684;&#x6D4F;&#x89C8;&#x6570;&#x636E;&#xFF0C;&#x6211;&#x4EEC;&#x53EA;&#x4F1A;&#x8BFB;&#x53D6;&#x4F60;&#x5F53;&#x524D;&#x6807;&#x7B7E;&#x9875;&#x7684;&#x6807;&#x9898;&#xFF0C;&#x7528;&#x6765;&#x5224;&#x65AD;&#x4F60;&#x662F;&#x5426;&#x5728;&#x8BBF;&#x95EE;&#x6211;&#x4EEC;&#x652F;&#x6301;&#x7684;&#x9875;&#x9762;(<a
            href="#supported-list">&#x652F;&#x6301;&#x7F51;&#x7AD9;&#x5217;&#x8868;</a>)&#xFF0C;&#x4EE5;&#x907F;&#x514D;&#x5F71;&#x54CD;&#x4F7F;&#x7528;&#x4F53;&#x9A8C;&#x7684;&#x4E8B;&#x60C5;&#x53D1;&#x751F;&#x3002;&#x6240;&#x6709;&#x5BF9;&#x4F60;&#x6D4F;&#x89C8;&#x6570;&#x636E;&#x7684;&#x6536;&#x96C6;&#x548C;&#x5904;&#x7406;&#x53EA;&#x4F1A;&#x53D1;&#x751F;&#x5728;&#x672C;&#x5730;&#xFF1B;&#x4E8B;&#x5B9E;&#x4E0A;&#x6211;&#x4EEC;&#x4E5F;&#x4E0D;&#x4F1A;&#x968F;&#x610F;&#x4FEE;&#x6539;&#x7F51;&#x7AD9;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x6211;&#x4EEC;&#x53EA;&#x4F1A;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x540C;&#x6B65;&#x811A;&#x672C;&#x6765;&#x76D1;&#x6D4B;&#x4F60;&#x64AD;&#x653E;&#xFF0C;&#x6682;&#x505C;&#x53CA;&#x66F4;&#x65B0;&#x8FDB;&#x5EA6;&#x7B49;&#x64CD;&#x4F5C;&#xFF08;&#x6211;&#x4EEC;&#x4E0D;&#x5F97;&#x4E0D;&#x8FD9;&#x6837;&#x505A;&#xFF09;&#x3002;<strong>&#x6240;&#x6709;&#x7684;&#x6E90;&#x7801;&#x90FD;&#x53EF;&#x4EE5;&#x5728;
            [&#x6211;&#x4EEC;&#x7684;&#x9879;&#x76EE;&#x4E3B;&#x9875;]&#x5BA1;&#x6838;(<a
              href="https://github.com/LouisYLWang/Sync-Sofa">https://github.com/LouisYLWang/Sync-Sofa</a>),
            &#x6211;&#x4EEC;&#x627F;&#x8BFA;&#x76EE;&#x524D;&#x505A;&#x7684;&#x6240;&#x6709;&#x4E8B;&#x60C5;&#x90FD;&#x662F;&#x5FC5;&#x8981;&#x4E14;&#x65E0;&#x5BB3;&#x7684;.</strong>
        </p>
      </li>
      <li>
        <p>&#x5982;&#x679C;&#x4F60;&#x53D1;&#x73B0;<strong>&#x6309;&#x94AE;&#x53D8;&#x7070;</strong>,
          &#x8BF7;&#x786E;&#x8BA4;&#x4F60;&#x662F;&#x5426;&#x5728;&#x6211;&#x4EEC;&#x652F;&#x6301;&#x7684;&#x7F51;&#x7AD9;&#x64CD;&#x4F5C;(<a
            href="#supported-list">&#x652F;&#x6301;&#x7F51;&#x7AD9;&#x5217;&#x8868;</a>).</p>
      </li>
      <li>
        <p>
          &#x5982;&#x679C;&#x4F60;&#x53D1;&#x73B0;&#x63D2;&#x4EF6;<strong>&#x65E0;&#x6CD5;&#x83B7;&#x53D6;&#x540C;&#x6B65;&#x7801;</strong>&#xFF0C;&#x8BF7;&#x6309;&#x4EE5;&#x4E0B;&#x987A;&#x5E8F;&#x68C0;&#x67E5;&#x95EE;&#x9898;&#xFF1A;
        </p>
        <ol>
          <li>&#x8BF7;&#x68C0;&#x67E5; <a href="#options-page">&#x9009;&#x9879;&#x9875;&#x9762;</a>
            &#x5E76;&#x70B9;&#x51FB;<code>&#x91CD;&#x7F6E;</code> &#x6309;&#x94AE;</li>
          <li>&#x8BF7;&#x53C2;&#x8003; <a href="#options-page">&#x9009;&#x9879;&#x9875;&#x9762;</a>
            &#x6839;&#x636E;&#x4F60;&#x6240;&#x5728;&#x7684;&#x4F4D;&#x7F6E;&#x9009;&#x62E9;&#x5E76;&#x8BBE;&#x7F6E;&#x5408;&#x9002;&#x7684;&#x670D;&#x52A1;&#x5668;
          </li>
          <li>&#x8BF7;&#x68C0;&#x67E5;&#x670D;&#x52A1;&#x5668;&#x5F53;&#x524D;&#x72B6;&#x6001; <a
              href="https://sync-status.onns.xyz/">https://sync-status.onns.xyz/</a>&#x662F;&#x5426;&#x6B63;&#x5E38;&#x542F;&#x52A8;
          </li>
          <li>
            &#x5982;&#x4EE5;&#x4E0A;&#x90FD;&#x4E0D;&#x80FD;&#x89E3;&#x51B3;&#x4F60;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x8BF7;&#x901A;&#x8FC7;<a
              href="https://github.com/LouisYLWang/Sync-Sofa/issues">&#x9879;&#x76EE;&#x53CD;&#x9988;&#x9875;&#x9762;</a>&#x6216;<a
              href="https://onns.xyz/sync-sofa/">&#x9879;&#x76EE;wiki&#x9875;&#x9762;</a>&#x53F3;&#x4E0B;&#x89D2;&#x7684;&#x53CD;&#x9988;&#x6309;&#x94AE;&#x901A;&#x77E5;&#x6211;&#x4EEC;&#x3002;
          </li>
        </ol>
      </li>
      <li>
        <p>
          &#x5982;&#x679C;&#x4F60;&#x53D1;&#x73B0;&#x63D2;&#x4EF6;<strong>&#x65E0;&#x6CD5;&#x6B63;&#x5E38;&#x540C;&#x6B65;&#x64CD;&#x4F5C;</strong>&#xFF0C;&#x8BF7;&#x6309;&#x4EE5;&#x4E0B;&#x987A;&#x5E8F;&#x68C0;&#x67E5;&#x95EE;&#x9898;&#xFF1A;
        </p>
        <ol>
          <li>
            &#x8BF7;&#x52A1;&#x5FC5;&#x786E;&#x8BA4;&#x4E24;&#x65B9;&#x7248;&#x672C;&#x53F7;&#x662F;&#x5426;&#x4E00;&#x81F4;&#xFF0C;&#x6B32;&#x68C0;&#x6D4B;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x9700;&#x6253;&#x5F00;<a
              href="chrome://extensions/">chrome extension
              page</a>&#xFF0C;&#x5E76;&#x627E;&#x5230;<code>Sync Sofa - Online Video Synchronizer *.*.*</code>&#xFF0C;&#x5176;&#x4E2D;
            <code>*.*.*</code> &#x4E3A;&#x5F53;&#x524D;&#x7248;&#x672C;&#x3002;</li>
          <li>&#x8BF7;&#x68C0;&#x67E5; <a href="#options-page">&#x9009;&#x9879;&#x9875;&#x9762;</a>
            &#x5E76;&#x70B9;&#x51FB;<code>&#x91CD;&#x7F6E;</code> &#x6309;&#x94AE;</li>
          <li>&#x8BF7;&#x53C2;&#x8003; <a href="#options-page">&#x9009;&#x9879;&#x9875;&#x9762;</a>
            &#x6839;&#x636E;&#x4F60;&#x6240;&#x5728;&#x7684;&#x4F4D;&#x7F6E;&#x9009;&#x62E9;&#x5E76;&#x8BBE;&#x7F6E;&#x5408;&#x9002;&#x7684;&#x670D;&#x52A1;&#x5668;
          </li>
          <li>&#x8BF7;&#x68C0;&#x67E5;&#x670D;&#x52A1;&#x5668;&#x5F53;&#x524D;&#x72B6;&#x6001; <a
              href="https://sync-status.onns.xyz/">https://sync-status.onns.xyz/</a>&#x662F;&#x5426;&#x6B63;&#x5E38;&#x542F;&#x52A8;.
          </li>
          <li>
            &#x5982;&#x4EE5;&#x4E0A;&#x90FD;&#x4E0D;&#x80FD;&#x89E3;&#x51B3;&#x4F60;&#x7684;&#x95EE;&#x9898;&#xFF0C;&#x8BF7;&#x901A;&#x8FC7;<a
              href="https://github.com/LouisYLWang/Sync-Sofa/issues">&#x9879;&#x76EE;&#x53CD;&#x9988;&#x9875;&#x9762;</a>&#x6216;<a
              href="https://onns.xyz/sync-sofa/">&#x9879;&#x76EE;wiki&#x9875;&#x9762;</a>&#x53F3;&#x4E0B;&#x89D2;&#x7684;&#x53CD;&#x9988;&#x6309;&#x94AE;&#x901A;&#x77E5;&#x6211;&#x4EEC;&#x3002;
          </li>
        </ol>
      </li>
    </ol>
    <h3 class="mume-header" id="%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E8%B0%83%E8%AF%95%E4%BF%A1%E6%81%AF">
      &#x5982;&#x4F55;&#x83B7;&#x53D6;&#x8C03;&#x8BD5;&#x4FE1;&#x606F;</h3>

    <ol>
      <li>&#x5728;<a href="#%E9%80%89%E9%A1%B9%E9%A1%B5">&#x9009;&#x9879;&#x9875;</a>&#x91CC;&#x6253;&#x5F00;
        <code>debug&#x6A21;&#x5F0F;</code>&#x3002;</li>
      <li>&#x5237;&#x65B0;&#x89C6;&#x9891;&#x9875;&#x9762;&#x3002;</li>
      <li><code>Shift + ctrl + i</code> &#x5728; Windows &#x4E0B; &#x6216;&#x8005; <code>Shift + cmd + i</code> &#x5728;
        MacOS &#x4E0B;.</li>
      <li>&#x9009;&#x62E9; <code>console</code> &#x6807;&#x7B7E;&#x9875;.</li>
    </ol>

  </div>











</body>

</html>